Tuesday, June 28, 2011

Associated entities and org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session

The problem:
I encountered this problem when attempting to save an entity that had a many-to-one association with an object that was being referenced multiple times in the same hibernate session. Hence the error below:

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [au.edu.apf.phenomebank.db.mouse.MouseStrain#5044]
        at org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:637)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:305)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:246)
Below is the hibernate mapping configuration file that I was using:

    <class name="au.edu.apf.phenomebank.inventory.mouse.EmbryoOocyte" table="embryo_oocyte">
        <id name="id" type="java.lang.Long">
            <generator class="increment"/>
        </id>
        
        <many-to-one name="mother" column="mother_id" cascade="save-update" not-null="true" />
        <many-to-one name="father" column="father_id" cascade="save-update" not-null="true" />
        <many-to-one name="strain" column="strain_id" cascade="save-update" not-null="true" />
        <property name="type" column="type" type="au.edu.apf.phenomebank.inventory.mouse.EnumEmbryoOocyteUserType"  not-null="true" />        
        <property name="breedingColour" column="breeding_colour" type="au.edu.apf.phenomebank.inventory.mouse.EnumBreedingColourUserType"  not-null="true" />
        
    </class>


 The Solution:

Since it was the associated objects that were causing the problem, the solution was to get Hibernate to merge them rather than attempt a save or update. This was achieved using the cascade propery as follows:

    <class name="au.edu.apf.phenomebank.inventory.mouse.EmbryoOocyte" table="embryo_oocyte">
        <id name="id" type="java.lang.Long">
            <generator class="increment"/>
        </id>
        
        <many-to-one name="mother" column="mother_id" cascade="merge,save-update" not-null="true" />
        <many-to-one name="father" column="father_id" cascade="merge,save-update" not-null="true" />
        <many-to-one name="strain" column="strain_id" cascade="merge,save-update" not-null="true" />
        <property name="type" column="type" type="au.edu.apf.phenomebank.inventory.mouse.EnumEmbryoOocyteUserType"  not-null="true" />        
        <property name="breedingColour" column="breeding_colour" type="au.edu.apf.phenomebank.inventory.mouse.EnumBreedingColourUserType"  not-null="true" />
        
    </class>