-->
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.  [ 6 posts ] 
Author Message
 Post subject: overriding equals in persistant objects
PostPosted: Wed Jan 07, 2004 5:48 pm 
Newbie

Joined: Wed Jan 07, 2004 5:40 pm
Posts: 6
Location: United Kingdom
Hi,

I want to override the equals() method in my persistant objects; I am of the understanding that Hibernate uses the id attribute to check equality; so I am assuming that there will be no side-effects if I override equals() ?

many thanks

Dan


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 07, 2004 8:09 pm 
Expert
Expert

Joined: Tue Sep 16, 2003 4:06 pm
Posts: 318
Location: St. Petersburg, Russia
Hmm... I don't think sentence "Hibernate uses the id attribute to check equality" is correct at all. for example, if Hibernate uses object id to lookup it in the cache could you say it was "an equality check"? I doubt.

When you put an object in Set for example, object's equals() method is used to check for equality. And Hibernate's Set is just an extension to JDK's Set - so there is nothing about id.

Anyway, as long as you follow standard Java rules about equals()/hashCode(), it should be safe to override them. For some classes (like composite-id) you even MUST do it.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 08, 2004 3:16 pm 
Newbie

Joined: Wed Jan 07, 2004 5:40 pm
Posts: 6
Location: United Kingdom
OK,

I guess a reason why I ask would be usefull.......

I have a facade class which has two methods ......

void addProduct(Product product)
List listProducts(..);

I am writing a junit test which in the setUp method adds a product and in the 'testListProducts' method, among other things tests to see if that product is in the list. However, as we all know, we cannot use == and also there is a convenient method in List i.e. contains(..) .

So in order for my original product and my listed product to be equal (in the business sense and for the contains method) I want to override equals(..).

The reason I mention testing equality with the id attribute .... when I was looking at the source code for session.saveOrUpdate, if it wanted to decide if to update rather than save, it did an equality check using the id element declared in the Product.hbm.xml file (in my case).

After this post I went ahead and added the equals(..) and all seems OK so far, I will repost if I hit any problems...

many thanks
dan


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 08, 2004 3:21 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
You should not use the database identifer value to test for equality. Implement equals()/hashcode() just like you would without Hibernate: By finding the best set of (unique) attributes in your entity. It doesn't have to be as good as a candidate key (really unique) attribute for a database table, but it definitely should be stable enough to use it for a short period in a Set.

For example: Most business classes often have a "created: Date" attribute. This ist just fine if you use it together with another attribute, for example a product name. It is unlikely that two products with the same name have been created in the same millisecond. Not good enough for a database, but good enough for the 30 seconds two products may be in the same Set on the client.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 09, 2004 7:55 am 
Expert
Expert

Joined: Tue Sep 16, 2003 4:06 pm
Posts: 318
Location: St. Petersburg, Russia
JFYI in our project we ended up with ID-based equals/hashCode to avoid instantiation of lazy/proxy objects when they are get inserted into Set for example.

But like you we needed a way to compare objects property-by-property which was needed for Unit tests only. Our solution may... seem strange at least :) We made all our classes Comparable and their compareTo method performs property-by property comparison.

So when we need to check if object is really the same, we use

object.compareTo(another) == 0

Below an example of a class

Code:
public class Task implements Comparable
{
    private Long id;
    private String name;
    private Double estimatedCost;
    private Company company;

    /* Comparison */

    public int hashCode()
    {
        return (id == null) ? 0 : id.hashCode();
    }

    public boolean equals(Object object)
    {
        if (object == this)
            return true;
        else if ( !(object instanceof Task) )
            return false;

        Task other = (Task) object;

        return Util.equals(id, other.getId());
    }

    public int compareTo(Object object)
    {
        if (object == this)
            return 0;

        Task other = (Task) object;
        int result;

        result = Util.compare(id, other.getId());
        if (result != 0)
            return result;

        result = Util.compare(name, other.getName());
        if (result != 0)
            return result;

        result = Util.compare(estimatedCost, other.getEstimatedCost());
        if (result != 0)
            return result;

        result = Util.compareAssociation(company, other.getCompany());
        if (result != 0)
            return result;

        return result;
    }
...
}


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 09, 2004 7:58 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
I wouldn't call this a good practice. You should of course not include "associations" in equals(), thus preventing lazy loading issues. But you should never use the identifier: Transient objects don't have an identifier value.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 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.