我有以下代码:
@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对象:
@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 表中的汽车和驾驶员关联起来。仅当我这样做时它才有效:
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);
}
所以,我想知道为什么这两种关联方式的工作方式不同
最佳答案
两个例子都有问题。
您应该养成这样的习惯:当您将两个实体相互关联时,双向关系的双方都得到正确维护,否则您会得到奇怪的行为,这可能会导致对象无法持久保存为在第二种情况下,或者遍历同一 session 边界内的对象图并获取 NullPointerException 。
您之前的情况应该将 Car
实例分配给 Driver
的汽车集合,就像您作为可嵌入示例的一部分所做的那样,以维护两个对象之间的正确关系。
也就是说,您的第一个用例可能在持久时工作的原因是因为可以推断类型,因为 Driver
的 cars 集合上的集合元素类型与以下类型相同:保持关系的反面。可嵌入情况并非如此,因此正如您所观察到的那样,实际上没有数据被持久化。
同样,正确的解决方案是确保双向关系的双方都已设置。这不仅确保代码在 Hibernate 下工作,而且可以跨持久性提供程序移植。
关于java - 将多对多关联移动到 @Embedded 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40243642/