java - JPA 在插入/更新时返回完整的外键实体
问题描述
我的目标是能够插入下面的对象,用户传入相关数据和外键的 id,并向用户返回一个包含完整外键对象的完整对象,而不仅仅是外键密钥标识。
@Data
@Entity
@EqualsAndHashCode(callSuper = false)
@Table(name = MY_OBJECT_TABLE)
public class MyObject {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "MY_OBJECT_ID", unique = true, nullable = false)
private Integer myObjectId;
@ManyToOne(targetEntity = ForeignObject.class, fetch = FetchType.EAGER)
@JoinColumn(name = "FOREIGN_OBJECT_ID", referencedColumnName = "FOREIGN_OBJECT_ID", nullable = false, insertable = false, updatable = false)
private ForeignObject foreignObject;
@Column(name = "FOREIGN_OBJECT_ID")
private Integer foreignObjectId;
@Column(name = "RANDOM_FIELD", nullable = false)
@NotNull
private Boolean randomField;
}
我正在尝试使用上述方法并插入但它只返回插入时的 foreignObjectId 而不是整个外来对象。
我尝试了以下方法以使其正常工作,但没有运气。
@Transactional
public MyObject create(MyObject myObject) {
MyObject createdMyObject = this.myObjectRepository.save(myObject);
return createdMyObject;
}
也试过
@Transactional
public MyObject create(MyObject myObject) {
MyObject createdMyObject = this.myObjectRepository.save(myObject);
return this.myObjectRepository.findById(createdMyObject.getMyObjectId());
}
我不确定我的域对象中是否有需要更改的内容,或者是否需要以某种方式更改我的创建方法。
当前输出为:
{
"myObjectId": 1,
"foreignObject": null,
"foreignObjectId": 3,
"randomField": true
}
预期输出为:
{
"myObjectId": 1,
"foreignObject": {
"foreignObjectId": 3,
},
"foreignObjectId": 3, // I don't care if this field stays here or not
"randomField": true
}
解决方案
问题在于您正在破坏域模型以尝试使其适合某些前端问题:
@ManyToOne(targetEntity = ForeignObject.class, fetch = FetchType.EAGER)
@JoinColumn(name = "FOREIGN_OBJECT_ID", referencedColumnName = "FOREIGN_OBJECT_ID",
nullable = false, insertable = false, updatable = false)
private ForeignObject foreignObject;
@Column(name = "FOREIGN_OBJECT_ID")
private Integer foreignObjectId;
您永远不会设置关系,而只是设置整数字段。
这将不起作用,因为调用EntityManager#persist
(通过 myObjectRepository.save)只是获取现有对象并使其持久化,即不会触发设置对 ForeignObject 的引用。
@Transactional
public MyObject create(MyObject myObject) {
//createdMyObject and myObject are same instance
MyObject createdMyObject = this.myObjectRepository.save(myObject);
return createdMyObject;
}
这将不起作用,因为将简单地从 Hibernate 的一级缓存中检索相同的实例(即您创建的没有关系集的实例):
@Transactional
public MyObject create(MyObject myObject) {
//createdMyObject, myObject and (due to 1st level cache)
//object returned from query are same
MyObject createdMyObject = this.myObjectRepository.save(myObject);
return this.myObjectRepository.findById(createdMyObject.getMyObjectId());
}
您可以通过执行以下操作可能使方法 2 起作用,但是正确的解决方案是删除 Integer 字段并正确设置关系。Spring MVC 控制器应该在 POST/PUT 请求中自动设置来自 ID 的引用{... "foreignObject" : 3 ...}
@PersistenceContect
EntityManager em;
@Transactional
public MyObject create(MyObject myObject) {
this.myObjectRepository.saveAndFlush(myObject);
em.clear(); //force reload from database
return this.myObjectRepository.findById(createdMyObject.getMyObjectId());
}
推荐阅读
- flutter - Flutter 相当于 Sencha 的 NestedList?
- android - 如何在存储库中初始化 okHttp 的 MockServer()?
- dart - 以阿拉伯语格式显示数字 Dart
- pyomo - 从 IPOPT 求解器获取:CPU 时间、#iterations 、目标函数的值并将它们保存在 Pyomo 上的向量中
- mongodb - Mongodb按字符串数组排序并使用索引
- git - 如何将我的分支继承的基本提交移动为当前分支中的第一个提交?
- python - FileNotFoundError:[Errno 2] 没有这样的文件或目录:'/home/ubicomp/ubicomp/questions_check'。(将文件放入 SFTP 服务器。)
- git - 如何在 SourceTree 中禁止空提交?
- android - 如何删除工具栏中的设置?
- usb - CarPlay MFI 资源