我模拟了你的用例,你可以在GitHub上找到测试。
这些是映射:
@Entity(name = "Car")
public static class Car implements Serializable {
@Id
@GeneratedValue
long id;
@Column(name="transmission", nullable = false)
String transmission;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "car")
Set<CarFactory> factories;
}
@Entity(name = "Factory")
public static class Factory implements Serializable {
@Id
@GeneratedValue
long id;
}
@Entity(name = "CarFactory")
public static class CarFactory implements Serializable {
@Id
@ManyToOne
@JoinColumn(name = "transmission", referencedColumnName = "transmission")
Car car;
@ManyToOne
@Id
Factory factory;
public void setCar(Car car) {
this.car = car;
}
public void setFactory(Factory factory) {
this.factory = factory;
}
}
以下是添加一些测试数据的方法:
doInTransaction(session -> {
Car car = new Car();
car.transmission = "Auto";
Car car1 = new Car();
car1.transmission = "Manual";
Factory factory = new Factory();
session.persist(factory);
session.persist(car);
session.persist(car1);
CarFactory carFactory = new CarFactory();
carFactory.setCar(car);
carFactory.setFactory(factory);
CarFactory carFactory1 = new CarFactory();
carFactory1.setCar(car1);
carFactory1.setFactory(factory);
session.persist(carFactory);
session.persist(carFactory1);
});
测试工作正常:
@Test
public void test() {
doInTransaction(session -> {
List<CarFactory> carFactoryList = session.createQuery("from CarFactory").list();
assertEquals(2, carFactoryList.size());
});
}
更新
由于以下唯一约束,您会收到异常:
alter table Car add constraint UK_iufgc8so6uw3pnyih5s6lawiv unique (transmission)
这是正常行为,因为 FK 必须唯一标识 PK 行。就像不能有多个具有相同 PK 的行一样,不能让 FK 标识符引用多个行。
映射是问题所在。您需要引用其他内容,而不是 .您需要一个唯一的汽车标识符,如VIN(车辆识别码),因此您的映射将变为:transmision
@Entity(name = "Car")
public static class Car implements Serializable {
@Id
@GeneratedValue
long id;
@Column(name="vin", nullable = false)
String vin;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "car")
Set<CarFactory> factories;
}
@Entity(name = "CarFactory")
public static class CarFactory implements Serializable {
@Id
@ManyToOne
@JoinColumn(name = "vin", referencedColumnName = "vin")
Car car;
@ManyToOne
@Id
Factory factory;
public void setCar(Car car) {
this.car = car;
}
public void setFactory(Factory factory) {
this.factory = factory;
}
}
这样,是唯一的,并且子关联可以引用一个且只能引用一个父项。vin