我有一个City
实体和一个Person
实体。我想在人与城之间建立一个OneToMany
关系,表明一个人居住的城市。它与人的单向OneToMany关系。
我的城市课程看起来像这样
@Entity
public class City {
@Id
@GeneratedValue
private Long id;
private String name;
...
}
人物实体看起来像这样
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(fetch = FetchType.EAGER, orphanRemoval = true)
private Set<City> livedInCities = new HashSet<City>();
...
}
在我的测试中,我只是创建一个城市并保存它。然后在保存该人员之前创建一个人并在其上添加已保存的城市实例。保存这个人后,一切都很好。
当我添加第二个人并在第二个人上添加相同的城市时,它会抛出唯一的约束违规。我不确定为什么会发生这种情况,因为在关系表中,这应该作为人2和城市1的新行插入。 测试代码
@Test
public void test() {
City chicago = new City();
chicago.setName("chicago");
City savedChicago = cityRepo.save(chicago);
Person john = new Person();
john.setName("john");
john.addCity(savedChicago);
Person savedJohn = personRepo.save(john);
Person tom = new Person();
tom.setName("tom");
tom.addCity(savedChicago);
Person savedTom = personRepo.save(tom);
System.out.println(savedTom);
System.out.println(savedJohn);
}
2015-07-02 18:11:21.026 WARN 5473 --- [main] o.h.engine.jdbc.spi.SqlExceptionHelper:SQL错误:23505,SQLState:23505 2015-07-02 18:11:21.026 ERROR 5473 --- [main] ohengine.jdbc.spi.SqlExceptionHelper:唯一索引或主键违规:“UK_B6XKGKBT91IXB0WE6N030RFPQ_INDEX_C ON PUBLIC.PERSON_LIVED_IN_CITIES(LIVED_IN_CITIES_ID)VALUES(1,1)” ; SQL语句:
完整的项目可在以下网站获得 https://github.com/adeelmahmood/jpatest-onetomany
我将不胜感激。
答案 0 :(得分:3)
问题在于,当你在Person类上使用@OneToMany注释时,你试图将两个人联系到同一个城市,你说每个城市只会涉及一个人。
可能的解决方案:
1 - (最推荐)将@OneToMany注释移动到City类。而不是拥有一套人在城市,在类City上实现一组人。另外,在Set of Person属性中添加@OneToMany注释。
2 - 您可以简单地使用@ManyToMany注释,并将所有其他内容保留原样。建议不要这样做,因为在你的情况下,在Person和City之间建立多对多没有意义
答案 1 :(得分:0)
您可以将集合类型从“设置”更改为“列表”,例如
private List<City> livedInCities = new ArrayList<City>();
设置中没有重复的项目。