6

Having such problem. Loaded collection of 2 objects (by primary key, using criteria). Then iterating them in the loop. When processing first object, somewhere very very far from this loop, is loaded object by same primary key as second object in loop. Here I see that System.identityHashCode() are different for this 2 objects. When processing second object from loop and trying to save it I get exception:

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

Trying to simulate this problem with simple object, loading , modifying, once more loading by PK, saving with different transaction propogation-s I always get same object instance... Could you please tell when it is possible to get second object instance in same session loading by PK?

2

2 Answers 2

4

In my situation problem was because: Firstly I have loaded some entity 'A' by primary key. Then I have loaded another entity 'B' using some criteria which through hbm mapping referenced this same (by PK) entity 'A' (for example B->some entity C->A) and hibernate didn't use already loaded 'A' entity, but loaded or created it secondly (I put breakpoint in entity 'A' constructor), thus in single session we have 2 entities with same PK but different instances. Trying to save entity 'A' we get exception 'NonUniqueObjectException'. Loading entity 'B' was somewere very very far away and under some conditions to reproduce and identify the problem. To find such places faster easily put breakpoint in 'NonUniqueObject' constructor and find who is loading this entity second time. By the way after I loaded entity 'B' I didn't try to call B->C->A, lazy='proxy' or without lazy at all, which means load C per request. Some mysteries to me...

Sign up to request clarification or add additional context in comments.

Comments

0

An easy way to implement equals() and hashcode() with a single primary key field like a String let's say or an Integer would be like so:

public boolean equals(Object obj) {
   if (obj == null) { return false; }
   if (obj == this) { return true; }
   if (obj.getClass() != getClass()) {
     return false;
   }
   ThisClass that = (ThisClass) obj;
   return this.id.equals( that.id );
}
public int hashCode() {
    returns id.hashCode();
}

for compound keys you're going to want to use code like this:

http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/builder/HashCodeBuilder.html

http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/builder/EqualsBuilder.html

1 Comment

I thought it was an anti-pattern to implement equals and hashCode on entity classes? A persistence context maintains at most one managed entity per PK anyways, so overriding these methods only serve to confuse developers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.