gpt4 book ai didi

java - JPA 在插入/更新时返回完整的外键实体

转载 作者:行者123 更新时间:2023-11-29 05:48:41 26 4
gpt4 key购买 nike

我的目标是能够在用户传入相关数据和外键 ID 的情况下插入以下对象,并向用户返回一个包含完整外键对象的完整对象,而不是只是外键 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 Controller 应使用 {... "foreignObject": 3 ...}

在 POST/PUT 请求中自动设置 ID 的引用
   @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());
}

关于java - JPA 在插入/更新时返回完整的外键实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56976234/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com