Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 313539 - [Hibernate] NonUniqueObjectException when saving a model with cyclical references
Summary: [Hibernate] NonUniqueObjectException when saving a model with cyclical refere...
Status: CLOSED FIXED
Alias: None
Product: EMF
Classification: Modeling
Component: cdo.core (show other bugs)
Version: 3.0   Edit
Hardware: PC Windows XP
: P3 critical (vote)
Target Milestone: ---   Edit
Assignee: Martin Taal CLA
QA Contact: Eike Stepper CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-05-19 10:51 EDT by Austin Teng CLA
Modified: 2019-11-08 03:14 EST (History)
2 users (show)

See Also:


Attachments
Stack trace (2.57 KB, text/plain)
2010-05-19 10:53 EDT, Austin Teng CLA
no flags Details
Test case (includes EMF model) (21.31 KB, application/x-zip-compressed)
2010-05-19 10:53 EDT, Austin Teng CLA
no flags Details
Proposed patch (1.94 KB, patch)
2010-05-19 10:55 EDT, Austin Teng CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Austin Teng CLA 2010-05-19 10:51:50 EDT
Build Identifier: 20100218-1602

The attached test code (HibernateStoreBidirectionalTest.zip) produces an exception (NonUniqueObjectException.txt) when attempting to save the model to a CDO Server configured to use a Hibernate Store.  The code is built against a January 18th nightly, fairly close to the head of the "Root_branching" branch.

The problem seems to be with references that introduce cycles in the object graph.  If multiple objects in the committed change sub-graph reference a common object, Hibernate will produce a NonUniqueObjectException while attempting to lazily initialize the second copy of the shared object during a saveOrUpdate operation.

The problem can be avoided by taking the following actions:

1. Make sure the following property is *NOT* set:

<property name="teneo.mapping.cascade_policy_on_non_containment" value="PERSIST,MERGE"/>

This will avoid calling persist or merge on related objects that should be unaffected by changes to the initial object.  For example, if A references B, and A is changed, B should remain unaffected.

2. Using the merge operation instead of saveOrUpdate in the write operation of the HibernateStoreAccessor (HibernateStoreBidirectionalFix.patch).  This appears to work, however, I'm unsure if there are more subtle consequences to the approach I've taken.

Reproducible: Always

Steps to Reproduce:
1. Launch a CDO Server locally that is configured with the following options:
   - Hibernate Store
   - Teneo dynamic mapping provider
   - HSQLDB (any database works, but this is easiest)
2. Disable the cascade policy property (see description) in the CDO Server config
   - Leaving it enabled will trigger a different failure point caused by the bidirectional reference between Student and School
   - Disabling it triggers a failure caused by the reflexive "sibling" relationship
3. Run the unit test included in the attachments
Comment 1 Austin Teng CLA 2010-05-19 10:53:18 EDT
Created attachment 169128 [details]
Stack trace
Comment 2 Austin Teng CLA 2010-05-19 10:53:57 EDT
Created attachment 169129 [details]
Test case (includes EMF model)
Comment 3 Eike Stepper CLA 2010-05-19 10:54:59 EDT
Martin, this seems to be Hibernate-related?
Comment 4 Austin Teng CLA 2010-05-19 10:55:02 EDT
Created attachment 169131 [details]
Proposed patch
Comment 5 Martin Taal CLA 2010-05-31 09:41:22 EDT
A patch to fix this issue has been attached to this bugzilla:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=315067
Comment 6 Martin Taal CLA 2010-05-31 12:43:22 EDT
A patch which solves this issue has been committed. Will be in the next build of CDO.
Comment 7 Eike Stepper CLA 2010-06-29 04:36:33 EDT
Available in 3.0 GA:
http://download.eclipse.org/modeling/emf/cdo/updates/3.0-releases/