-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: hashCode question
PostPosted: Tue Jan 17, 2006 12:09 pm 
Newbie

Joined: Mon Mar 21, 2005 9:41 am
Posts: 12
Hello to everybody,

I have the problem concerning hashCode/equals. I have 2 entities DbRssSpider and DbRssProperty an the following relation:


Spider:
Code:
@OneToMany(mappedBy = "spider", cascade = { CascadeType.ALL}, targetEntity = DbRssProperty.class)
   @OrderBy("id")
    public Set<DbRssProperty> getProperties()
   {
      return propertySet;
   }
   


Property:
Code:
@ManyToOne()
   @JoinColumn(name = "spiderId")
   public DbRssSpider getSpider()
   {
      return spider;
   }


As specified with the cascade-annotation, I want a property to be persistet when added to the set of the spider. Additionally, I want two persitent instances of DbRssProperty to be equal if they have the same id. So I had to override equals and hashCode. The Problem is the following:
If I use the id in hashCode, its impossible to implement the properties-Set with a java.util.HashSet because the added instances a hashed first and persisted second(this changes the hash-value).
If I don't use the id in hashCode, it's possible that two properties with the same id have different hashCodes.

Does anyone have an idea of how to implement hashCode?

Thank you in advance,
Mathias


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 17, 2006 12:42 pm 
Regular
Regular

Joined: Sat Nov 19, 2005 2:46 pm
Posts: 69
I don't know if it's totally a good idea (maybe sombody can show me the flaws?) - but I init the hash code lazily, and check for the object being brand new:
From within the class:
Code:
  protected volatile transient Integer hash = null;
  /**
   * Intended to be a "Hibernate safe" hash code calculation.
   * The basic intention is that objects with the same id represent the same entity,
   * and thus are equal and also should have the same hash code.
   * Two objects which are both not persistent (isNew() returns true) are not equal to each other,
   * and should therefore have different hash codes if possible.
   * The main danger is in the hash code changing when a new object is made persistent,
   * as the id is assigned a new (meaningful) value at that point;
   * if this occurs objects can be unrecoverable from HashSets, HashMaps, etc.
   * The hash code is therefore made immutable for the lifetime of the object but is lazily calculated
   * to maximize chances of the object being in a persistent state before it is used in hashing.
   * If an object is in a HashSet (or similar) prior to being newly persisted, it will at least be recoverable
   * by using the exact same object reference, but will not be recoverable by a new reference created using session.load(Class, Serializable).
   * This design leaves one remaining flaw: two new objects which are then persisted to the same id
   * will have different hash codes and thus violating the hashCode() contract of the Java language:
   * "<quote>If two objects are equal according to the equals(Object) method,
   * then calling the hashCode method on each of the two objects must produce the same integer result.</quote>"
   * However, given that Hibernate will not allow this, it is not considered a problem:
   * session.save(Object) will always assign an incremental id value to a newly persistent object, regardless of any id set by the application,
   * provided the hbm.xml specifies &lt;generator&gt; and does not use &lt;generator class="assigned"/&gt;;
   * session.update(Object) will throw a NonUniqueObjectException.
   * @see CodeObject#hashCode()
   */
  public int hashCode()
  {
    if(hash == null)
    {
      if(isNew())
      {
        hash = new Integer(super.hashCode());
      }
      else
      {
        // hash algorithm taken from "Effective Java Programming Language Guide" (http://java.sun.com/docs/books/effective/)
        hash = new Integer(37 + ((int)(id ^ (id >>> 32))));
      }
    }

    return hash.intValue();
  }

_________________
Stewart
London, UK


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.