0

Working with Hibernate-EntityManager 4.3.5 I'm getting the HibernateException: Found two representations of the same collection.

The scenario is that I have 2 entities A and B; both with relationship to a third entity C. A also have a relationship with B. Let's try to make it clear:

A -> OneToOne with B and C

B -> OneToMany with C

A and B are loaded in different transactions (Interceptors) but next I make A.setXXX(B) and do a entityManager.merge(A); -- A have an instance of C and B another, but they represent the same instance (same ID or primary key). Because of that, I'm getting this error - in fact, I have 2 different instances of C (one with A and another with B) that represent the same entity (same PK). How to solve this? I thought of doing something like B.setXXX(a.getXXX()) but it sounds very messy. Any suggestions?

Valerio Lopes
  • 79
  • 1
  • 9
  • Can you add your mapping files and entity class? – Mihir Jun 08 '15 at 07:07
  • If you are using attribute cascade="all",Just remove the cascade="all" from your mapping file and execute . – Mihir Jun 08 '15 at 07:12
  • I corrected a wrong relationship in the text; actually A -> OneToOne with C (unidirectional relationship; no cascade present) and B -> OneToMany with C (with cascade=All; also this is a bidirectional one - C maps B with ManyToOne). I'll try removing it. – Valerio Lopes Jun 08 '15 at 15:19
  • Looks like it might be related to this: http://stackoverflow.com/questions/10550511/illegalstateexception-with-hibernate-4-and-manytoone-cascading/15359846#15359846 – Tobb Jun 08 '15 at 15:21
  • That's it @Tobb -- this behaviour of merge() method transversing the object graph makes sense. When I call em.merge(A) I have the following situation: A points to B and C; B points to a List of C; C points to another instance of B, which in turn points to a List of C; However, both instances of B represent the same object (same db PK). The same applies to the lists of C, so it's fair to get the message **Two representations of the same collection** I'll have to remove the cascade=All in the relationship B -> C so the merge won't transverse this branch of the graph. – Valerio Lopes Jun 08 '15 at 20:15
  • I think the real issue in these situations is the fact that you have multiple objects with the same database identifier in your object graph. Inside a transaction, same database identifier will mean same object identifier, and this is the way JPA is meant to work. I find using JPA entites outside of transaction "less good" for multiple reasons, and I don't think that is the way they are meant to be used. Consider widening your transaction, or make sure the logic to make the changes is done within a transaction. Depends a bit on your specific use case. – Tobb Jun 08 '15 at 20:26
  • Yeah -- the reason the objects are first retrieved in different transactions is that I'm using a MVC framework that 'converts' Ids from hidden fields into objects (i.e, querying the database). Because it's part of the framework lifecycle, it's a different transaction. – Valerio Lopes Jun 08 '15 at 22:11
  • Thanks too @Mihir. Now here's the awkward situation: we found the answer but there's no formal answer to accept. – Valerio Lopes Jun 08 '15 at 23:42
  • @Valerio Lopes,Which one solved your query mark that as useful information to the post. – Mihir Jun 09 '15 at 05:58

1 Answers1

1

Thanks to @Tobb and @Mihir I could figure out what was going on - When I call entityManager.merge(A) I have the following situation:

A points to B and C; B points to a List of C; C points to another instance of B, which in turn points to a List of C;

However, both instances of B represent the same object (same db PK). The same applies to the lists of C, so it's fair to get the message Two representations of the same collection I'll have to remove the cascade=All in the relationship B -> C so the merge won't transverse this branch of the graph.

Valerio Lopes
  • 79
  • 1
  • 9