Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[eclipselink-users] Duplicate insert and constraint violation with circular relationships

We are using EclipseLink 2.4.2 in a J2EE environment with WebLogic 10.3.6.

Our data model has one main table and several circular relationships, such as  A <->> B <<-> C <->> D <<-> A and A <<-> E <->> A.  All relationships cascade merge, so a merge of any one object generally cascades to all other objects in that object graph.

While this generally works without an issue, we have a few situations where EclipseLink will attempt to insert a new entity twice, resulting in a constraint violation.  This code causes such a failure in our system:

    EntityManager em = /* injected EntityManager instance */

    A a = em.find(A.class, 86); 
    C c = em.find(C.class, 2950); 

    B b = new B(); 
    b.setA(a);
    a.bList.add(b);
    b.setC(c);
    c.bList.add(b);
           
    em.merge(a);

This results in two statements to insert into B with keys 86 and 2950, which is a constraint violation (and anyways incorrect).  The interesting thing is that this only happens if both "a" and "c" are attached at the time of the merge, as they are in the above code.  If either is detached, then only one insert statement is issued, and it works.

My guess is that the circular relationships are somehow messing up the cascade merge operation, perhaps EclipseLink is seeing the relationships A -> B and inserting B, and then the relationships A -> D -> C -> B and inserting it again?  I know that EclipseLink handles circular relationships by default, but I wonder if this situation is not supported somehow.

I also find it curious that EclipseLink does the right thing if the objects are detached, suggesting a different internal code path when merging with attached vs. detached objects.

My first question is if this behavior sounds like a bug, and if so if it is a known issue.  I have seen this same issue mentioned on Hibernate and ObjectDB discussion boards and so wonder if it has come up with EclipseLink.  My second question is what are possible workarounds?

We have explored disabling cascade merge on certain relationships, such as the D <<-> A relationship in my example above, to "break the cycle".  However in reality our data model has about 120 entities, many of which are in various circular relationships, and it might be a big job to get this right, if that is possible at all.  Another possibility is to always detach our object graph before merging, which seems extraneous, but does avoid the problem code path and works reliably.

Thanks in advance for any info or tips.

Randy



Back to the top