简体   繁体   中英

Unique contraint violation on OneToMany relationship

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;
  ...
}

link to City class code

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>();
   ...
}

link to Person class code

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);

}

link to Test code

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM