Thread:
 Using properties of an object for equals and hash ... 
 andrewGoedhart   26 Jan 2005, 16:45 
 Re: Using properties of an object for equals an... 
 Ras_Nas   05 Feb 2005, 02:50 

Comment
Prev. thread 
 Next thread
 
Prev. posting 
 Next posting
From: andrewGoedhart (26 Jan 2005, 16:45) Replies: 1, Views: 37782
Subject: Using properties of an object for equals and hash code ...
The reccomendation of using the properties of an object rather then 
the object identity and or synthetic primary key is just as broken as 
the problem we are trying to highlight and solve. This is because if 
any of the properties used in the composite key are edited all the 
problems listed by the main author will occur. In some cases it could 
be worse because the problems associated with changes to the 
properties making up the new key will most likely only show up during 
production. 

The solution actually lies in hibernates contract of maintaining a 
single instance per object in the session cache. 

Equals is easy:

public boolean equals(Object other){
 if( this == other) 
    return true;
 if( (this.id == null) || (other.id== null))
   return false;
 return this.id.equals(other.id);
}

Here we assume that new objects are always different unless they are 
the same object. If an object is loaded from the database it has a 
valid id and therefore we can check against object ids.

Hash code is more difficult we need to ensure that if:
A==B 
then 
A.hashcode == B.hashcode

If we base it on Ids which dont change once assigned then we only have 
to ensure that new objects also obey the above contract within the 
scope of the session. 


private Integer hashcodeValue = null;

public synchronized int hashCode(){
  if( hashcodeValue == null){
    if( id == null){
      hashcodeValue = new Integer(super.hashcode());
    } else {
      hashcodeValue = generateHashCode(id);
    }
  }
  return hashcodeValue.intValue();
}

What we are doing here is ensuring that once a hshcode value is used, 
it never changes for this object. This allows us to use object 
identity for new objects and not run into the problems listed above. 
In fact the only case where this is a problem is when we save a new 
object, keep it around after we close the session, load a new instance 
of the object in a new session and then compare them. 

in this case we get A==B but a.hashcode != b.hashcode

The above functions work in all other scenarios and don't lead to 
broken implementations when the propety of the object are edited. The 
whole point in generating synthetic primary keys in the first place is 
to avoid having a primary key which is dependant on an object  
property and which therefore may change during the life time of the 
object.
Prev. thread 
 Next thread
 
Prev. posting 
 Next posting
© Copyright 2006, Red Hat Middleware, LLC. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc. [Privacy Policy]