I have a City
entity and a Person
entity. I want to setup a OneToMany
relationship from Person to City indicating which cities a person has lived in. Its a uni-directional OneToMany relationship from Person.
My City class looks like this
@Entity
public class City {
@Id
@GeneratedValue
private Long id;
private String name;
...
}
The person entity looks like this
@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>();
...
}
In my test I am simply creating a city first and saving it. Then creating a person and adding the saved city instance on it before saving that person. After saving the person, everything is fine.
When I add a second person and add the same city on the second person, it throws a unique constraint violation. I am not sure why this is happening because in the relationship table, this should be inserted as a new row for person 2 and city 1. Test code
@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] ohengine.jdbc.spi.SqlExceptionHelper : SQL Error: 23505, SQLState: 23505 2015-07-02 18:11:21.026 ERROR 5473 --- [ main] ohengine.jdbc.spi.SqlExceptionHelper : Unique index or primary key violation: "UK_B6XKGKBT91IXB0WE6N030RFPQ_INDEX_C ON PUBLIC.PERSON_LIVED_IN_CITIES(LIVED_IN_CITIES_ID) VALUES (1, 1)"; SQL statement:
The complete project for this is available at https://github.com/adeelmahmood/jpatest-onetomany
I would appreciate any help.
The problem is that you are trying to relate two Persons to the same City when by using @OneToMany annotation on the Person class you are saying that each City only will relate to one single Person.
Possible solutions:
1 - (Most recommended) Move @OneToMany annotation to the City class. Instead of having a Set of Cities on Person, implement a Set of Person on the class City. Also, adding the @OneToMany annotation on the Set of Person attribute.
2 - You can simply use the @ManyToMany annotation and leave all the rest like it is. This is not recommended because in your case it does not make sense to have a many-to-many between Person and City
You can change collection type from "Set" to "List" like
private List<City> livedInCities = new ArrayList<City>();
The Set don't contain duplicate items.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.