Hello all,
I am getting a org.hibernate.NonUniqueObjectException from Hibernante that I can't explain and need some guidance. I essentially load an peristed object in a
stateless session EJB, detach it to the web tier, make changes there, pass it back to the session bean, and merging into a new Hibernante Session instance which is where I get this exception indicating that the Employee object is not unique in the session. I don't understand how I can get this NonUnique error when I am merging a detached object in a new Hibernate Session -- what could be in a brand new Hibernante Session instance would make the detached object non-unique?
First, a litlte background. I am using Hibernate 3.2 with stateless session EJBs under WebSphere. I have two classes, Compdata and Employees, that are related by a many-to-many join table named COMPDATA_X_EMPLOYEES. Compdata has been made the owner of the relationship by setting inverse = "false" (see hbm files below). I am also using optimistic locking with the version property.
I have code that loads the Employee object in an EJB, returns the Employee object to the web tier as a detached object, the user makes mods, and then saves those changes which goes back to the EJB, merges the Employee object into a new Hibernate Session instance, and performs a saveUpdate on the changes. That worked great.
However, I was just presented with the need to modify this sequence by joining the Employee's Compdata records and returning the desired Employee record to the web tier along with the collection of related Compdata objects (which is always just one object now -- long story). So the user will make changes to the Employee object and possibly change the Employee's Compdata collection to reference a different Compdata. When they attempt to save it and my code attemtps to merge the Employee object into a NEW Hibernante Session, I receive this NonUniqueObjectException. When I change my code to NOT join the Compdata object (which implies that when I merge the Employee object into a new Hibernante Session, there are no Compdata collections in the Employee object),
I do not receive this exception any longer. The exact exception is as follows:
Code:
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.faweb.entities.Employees#1]
So what could be happening here with the joined Compdata objects that makes Hibernnate believe the Employee object is not-unique?
Here is the segment of code that causes the exception:
Code:
public Employees UpdateEmployeeAndEmployerRef(Employees emp, Compdata compData) throws com.faweb.exceptions.FAWebUpdateError {
Session session = null;
try {
if (emp == null) {
throw new com.faweb.exceptions.FAWebUpdateError("Unable to save changes to Employee as the data is invalid. Please logout and try again. If problem persists, contact the system administrator");
}
myLogger.debug("FAEJB: Getting Hibernate Session object");
session = HibernateUtil.getSessionFactory().getCurrentSession();
session.getTransaction().begin();
myLogger.debug("FAEJB: Merging changes to emp");
session.merge(emp);
***EXCEPTION THROWN BY HIBERNANTE HERE***
Hibernante HBM files:
Code:
<hibernate-mapping>
<class name="com.faweb.entities.Compdata" table="COMPDATA" schema="FAWEB">
<id name="companyid" type="int">
<column name="COMPANYID" />
<generator class="identity" />
</id>
<version name="version" type="java.lang.Integer" unsaved-value="null">
<column name="VERSION" />
</version>
<set name="employees" inverse="false" table="COMPDATA_X_EMPLOYEES" cascade="persist,merge,save-update" optimistic-lock="false">
<key>
<column name="COMPANYID" not-null="true" />
</key>
<many-to-many entity-name="com.faweb.entities.Employees" fetch="join">
<column name="EMPLOYEE_ID" not-null="true" />
</many-to-many>
</set>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="com.faweb.entities.Employees" table="EMPLOYEES">
<id name="employeeId" type="int">
<column name="EMPLOYEE_ID" />
<generator class="identity" />
</id>
<version name="version" type="java.lang.Integer" unsaved-value="null">
<column name="VERSION" />
</version>
<set name="compdatas" inverse="true" table="COMPDATA_X_EMPLOYEES" cascade="persist,merge,save-update" optimistic-lock="false">
<key>
<column name="EMPLOYEE_ID" not-null="true" />
</key>
<many-to-many entity-name="com.faweb.entities.Compdata" fetch="join">
<column name="COMPANYID" not-null="true" />
</many-to-many>
</set>
</class>
</hibernate-mapping>