我有以下代码:
@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);
}
所以,我想知道为什么这两种关联方式的工作方式不同
答案 0 :(得分:1)
这两个例子都有问题。
你应该习惯于确保当你将两个实体相互关联时,双向关系的双方都得到适当的维护,否则你会得到一些奇怪的行为,这可能导致不坚持第二种情况下的对象,或者在同一会话的边界内遍历对象图并获得NullPointerException
s。
您之前的案例应该是将Car
个实例分配给Driver
的汽车收藏品,就像您将其作为可嵌入示例的一部分一样来维护两个对象之间的正确关系。
那就是说,你第一次使用案例的原因可能是在持续时间工作是因为可以推断出类型,因为Driver
的汽车收藏中的收集元素类型是相同的管理保持关系的反面的类型。对于可嵌入的情况,情况并非如此,因此,为什么实际上没有数据像您观察到的那样持续存在。
同样,正确的解决方案是确保双向关系的两侧都已设置。这不仅可以确保代码在Hibernate下工作,而且可以在持久性提供程序中移植。