我有 2 个班级:司机和汽车。汽车表在单独的过程中更新。我需要的是在 Driver 中拥有属性,使我能够阅读完整的汽车描述并仅写入指向现有汽车的 Id。这是例子:
@Entity(name = "DRIVER")
public class Driver {
... ID and other properties for Driver goes here .....
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "CAR_ID")
private Car car;
@JsonView({Views.Full.class})
public Car getCar() {
return car;
}
@JsonView({Views.Short.class})
public long getCarId() {
return car.getId();
}
public void setCarId(long carId) {
this.car = new Car (carId);
}
}
Car 对象只是典型的 JPA 对象,没有对 Driver 的反向引用。
所以我试图通过这个实现的是:
- 我可以使用详细的 JSON 视图阅读完整的汽车描述
- 或者我只能在 Short JsonView 中读取汽车的 Id
- 最重要的是,在创建新驱动程序时,我只想传入汽车的 JSON ID。这样我就不需要在坚持期间对汽车进行不必要的读取,而只需更新 Id。
我收到以下错误:
object references an unsaved transient instance - save the transient instance before flushing : com.Driver.car -> com.Car
我不想在数据库中更新 Car 的实例,而只是从 Driver 中引用它。知道如何实现我想要的吗?
谢谢你。
更新:忘记提及我在创建驱动程序期间传递的汽车 ID 是数据库中现有汽车的有效 ID。
原文由 Andrei V 发布,翻译遵循 CC BY-SA 4.0 许可协议
该错误消息意味着您的对象图中有一个未明确保留的瞬态实例。对象在 JPA 中可以具有的状态的简短回顾:
错误消息告诉您的是,您正在使用的(托管/分离的)驱动程序对象持有对 Hibernate 未知的 Car 对象的引用(它是瞬态的)。为了让 Hibernate 理解任何从 Driver 引用的未保存的 Car 实例也应该被保存,你可以调用 EntityManager 的持久化方法。
或者,您可以在 persist 上添加一个级联(我想,只是从我的头顶开始,还没有测试过),这将在持久化 Driver 之前在 Car 上执行 persist。
如果您使用 entitymanager 的合并方法来存储驱动程序,您应该添加
CascadeType.MERGE
代替,或两者: