我有2个类(class):驾驶员和汽车。汽车表在单独的过程中更新。我需要的是在Driver中具有属性,该属性使我可以阅读完整的汽车说明,并仅写入指向现有Car的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);
}
}
汽车对象只是典型的JPA对象,没有向后引用驱动程序。
所以我想要达到的目的是:
1)我可以使用详细的JSON View阅读完整的汽车描述
2)或者我只能在短JsonView中读取汽车的ID
3)最重要的是,在创建新的Driver时,我只想传递汽车的JSON ID。
这样,我在持久化期间无需对汽车进行不必要的读取,而只需更新ID。
我收到以下错误消息:“对象引用了一个未保存的 transient 实例-在刷新之前保存该 transient 实例:com.Driver.car-> com.Car”
我不想在数据库中更新Car的实例,而只是从Driver引用它。知道如何实现我想要的吗?
谢谢。
更新:
忘了提及,我在创建驱动程序期间通过的汽车ID是DB中现有汽车的有效ID。
最佳答案
该错误消息表示您的对象图中有一个 transient 实例,没有明确保留。简短回顾一下对象在JPA中可以具有的状态:
错误消息告诉您,正在使用的(托管/分离)驱动程序对象持有对Hibernate未知( transient )的Car对象的引用。为了使Hibernate理解,也应该保存从Driver引用的要保存的Car的所有未保存实例,也可以保存,您可以调用EntityManager的persist-method。
另外,您可以在持久性上添加一个层叠(我想,只是从我的头顶上还没有测试过),它将在持久化驱动程序之前在Car上执行持久化。
@ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.PERSIST)
@JoinColumn(name = "CAR_ID")
private Car car;
如果您使用entitymanager的合并方法来存储驱动程序,则应添加
CascadeType.MERGE
或同时添加两者:@ManyToOne(fetch=FetchType.LAZY, cascade={ CascadeType.PERSIST, CascadeType.MERGE })
@JoinColumn(name = "CAR_ID")
private Car car;