JPA 多对一关系 - 只需要保存 Id

2022-09-01 00:50:55

我有2个班级:司机和汽车。汽车表在单独的流程中更新。我需要的是司机中的属性,允许我阅读完整的汽车描述,并只写指向现有汽车的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视图阅读完整的汽车描述
  2. 或者我只能在简短的JsonView中读取汽车的Id
  3. 最重要的是,在创建新的驱动程序时,我只想传递汽车的JSON ID。这样,我不需要在持久化期间为汽车进行不必要的读取,而只需更新Id即可。

我收到以下错误:

object references an unsaved transient instance - save the transient instance before flushing : com.Driver.car -> com.Car

我不想在数据库中更新汽车的实例,而只是从驱动程序中引用它。任何想法如何实现我想要的?

谢谢。

更新:忘记提到我在创建驱动程序期间通过的汽车的ID是DB中现有汽车的有效ID。


答案 1

您可以通过呼入来执行此操作:getReferenceEntityManager

EntityManager em = ...;
Car car = em.getReference(Car.class, carId);

Driver driver = ...;
driver.setCar(car);
em.persist(driver);

这将不会从数据库执行 SELECT 语句。


答案 2

作为对 okutane 的回答,请参阅 snippet:

@JoinColumn(name = "car_id", insertable = false, updatable = false)
@ManyToOne(targetEntity = Car.class, fetch = FetchType.EAGER)
private Car car;

@Column(name = "car_id")
private Long carId;

因此,这里发生的事情是,当您要执行插入/更新时,您只需填充字段并执行插入/更新。由于 car 字段是不可插入的,并且不可更新的 Hibernate 不会抱怨这一点,并且因为在数据库模型中,您只会将您填充为外键,因此此时这就足够了(并且您在数据库上的外键关系将确保您的数据完整性)。现在,当您获取实体时,Car 字段将由 Hibernate 填充,为您提供灵活性,只有您的父母在需要时才能获取。carIdcar_id


推荐