Reputation: 3
I have the situation where I have a class A having a OneToMany relationship to class B. Class B only consists of a few attributes like id, firstName and lastName. The id is generated through UUID. Since it is very likely that very much instances of A will reference an instance of B with the same values for firstName and lastName plus those values in instances of B are very unlikely to ever change. So I decided to avoid duplicates and let reference instances of A to the same instances (in the database) of B if the other parameters are the same.
Example:
b: "John Doe"
a: a1 ("Foo Bar", "John Doe"), a2 ("John Doe", "Alan Smith").
To achieve this I always check the database for an already existing record with the very same parameters if a new B is added to A. If so, I'll just overwrite the id of that instance of B with the one from the database and add it to A afterwards.
Now here comes my problem. Everything is working fine but if I persist an A where I manually changed the Id of an B so that it has the same Id as a B already existing in the database I'll get an Exception:
Caused by: org.hibernate.exception.ConstraintViolationException:
Duplicate entry '2cfa1412-5f64-4a9c-b55c-f7db1148bef9' for key 'PRIMARY'
So my questions are:
Best regards
Upvotes: 0
Views: 796
Reputation: 691735
First of all, you don't have a OneToMany, but a ManyToMany.
Now, to fix your problem, don't assign the ID of the attached B to your detachedB, but replace the detached B by the attached one:
Set<B> bs = new HashSet<B>(a.getBs()); // copy the list of Bs
a.getBs().clear();
for (B b : bs) {
B existingB = searchBWithSameValuesAs(b);
if (existingB != null) {
a.getBs().add(existingB);
}
else {
em.persist(b);
a.getBs().add(b);
}
}
Upvotes: 1