将 many-to-many 关联移动到 @Embedded object

move many-to-many association to @Embedded object

我有以下代码:

@Entity
public class Car {

    @Id
    @GeneratedValue()
    private Long id;

    @ManyToMany(fetch = FetchType.LAZY, mappedBy = "cars")
    private List<Driver> drivers = new ArrayList<>();

    //other properties, getters and setters
}

@Entity
public class Driver {

    @Id
    @GeneratedValue()
    private Long id;

    @ManyToMany
    private List<Car> cars = new ArrayList<>();

    //other properties, getters and setters
}

public void addCar(List<Driver> drivers) {
    Car car = new Car();

    car.setDrivers(drivers);

    //set other properties

    carRepository.save(car);
}

而且效果很好。

出于某种原因,我想将驱动程序列表移至@Embedded object:

@Entity
public class Car {

    @Id
    @GeneratedValue()
    private Long id;

    @Embedded
    private DriverInfo driverInfo;

    //other properties, getters and setters
}

@Embeddable
public class DriverInfo {

    @ManyToMany(fetch = FetchType.LAZY, mappedBy = "cars")
    private List<Driver> drivers = new ArrayList<>();

    //other properties, getters and setters
}

但是添加汽车并不会在 drivers_cars table 中关联汽车和司机。只有当我这样做时它才有效:

public void addCar(List<Driver> drivers) {
    Car car = new Car();

    car.setDrivers(drivers);

    for (Driver driver : drivers) {
        driver.getCars.add(car);
    }

    //set other properties

    carRepository.save(car);
}

所以,我想知道为什么这两种关联方式的工作方式不同

两个例子都有问题。

你应该养成习惯,当你将两个实体相互关联时,双向关系的双方都得到了适当的维护,否则你会出现奇怪的行为,这可能会导致不持久objects 与您的第二种情况一样,或者在相同 session 的边界内遍历 object 图并获得 NullPointerExceptions。

您之前的案例应该是将 Car 实例分配给 Driver 的汽车 collection 就像您在维护可嵌入示例中所做的那样两个 object 之间的正确关系。

就是说,您的第一个用例可能在持续时间工作的原因是因为可以推断类型,因为 Driver 的汽车上的 collection 元素类型 collection 是保存关系反面的同一托管类型。可嵌入的情况并非如此,因此为什么没有数据像您观察到的那样实际保留。

同样,正确的解决方案是确保双向关系的双方都已设置。这不仅确保代码在 Hibernate 下工作,而且可以跨持久性提供程序移植。