facebook

Generated equals and hashcode: Not for Sets?

  1. MyEclipse Archived
  2.  > 
  3. Database Tools (DB Explorer, Hibernate, etc.)
Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #229243 Reply

    jdemmon
    Member

    The Hibernate mapping tool generated this equals() method for AbstractFoo.java:

     public boolean equals(Object rhs)
        {
            if (rhs == null)
                return false;
            if (! (rhs instanceof Foo))
                return false;
            Foo that = (Foo) rhs;
            if (this.getRowId() != null && that.getRowId() != null)
            {
                if (! this.getRowId().equals(that.getRowId()))
                {
                    return false;
                }
            }
            return true;
        }

    The primary key in this case is a String, which is null until Hibernate assigns a value, which may not occur until the session is flushed.

    This method returns true between any two new unsaved instances of Foo. It also returns true if (this.getRowId() == null && that.getRowId() != null). The way equals() is written, I’ll never be able to add more than one unsaved instance of Foo to a Set. These observations also hold true for when the right hand side is a subclass of Foo.

    Also, take a look at the hash code method:

    public int hashCode()
        {
            if (this.hashValue == 0)
            {
                int result = 17;
                int rowIdValue = this.getRowId() == null ? 0 : this.getRowId().hashCode();
                result = result * 37 + rowIdValue;
                this.hashValue = result;
            }
            return this.hashValue;
       }

    So for all new (unsaved) instances of Foo the hashcode is the same? Better hope you don’t want to put more than a few of these in a Set or a Map!

    #229266 Reply

    Riyad Kalla
    Member

    Thank you for bringing this to our attention we will have a look right away.

    #229307 Reply

    support-jeff
    Member

    Excellent points. A lot of this has been hash-out on the hibernate wiki and in the forums for hibernate:

    http://hibernate.org/109.html

    Point being that there is not much we can do but rely on the identity.

    As for the equals() code, definitely a bug. This is the pattern generated for objects with composite keys. I am surprised that no one had noticed it before. Fortunately for you (and other users) you can modify the Velocity template in the com.genuitec.eclipse.hibernate plugin (templates/mappedobject.vm) to do the right thing when generating the code. We will get a fix in as soon as possilble.

    #229436 Reply

    support-jeff
    Member

    Doing some more follow up:

    (1) Can you identify a case where a subclass POJO and its base class POJO would have identical PK id values (other than the case of unsaved)? I cannot think of a case where this would occur.

    (2) The equals() bug is present for any mapped POJO with a non-primitive identifier (and the case you note above is for String, not for composite id classes; the latter are also broken in a similar way). We will be fixing this in the upcoming 4.0 release (probably won’t make the first milestone release; definitely the second tho).

    #238060 Reply

    airframes
    Member

    This message has not been recovered.

    #238097 Reply

    Brian Fernandes
    Moderator

    This message has not been recovered.

Viewing 6 posts - 1 through 6 (of 6 total)
Reply To: Generated equals and hashcode: Not for Sets?

You must be logged in to post in the forum log in