Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 12 posts ] 
Author Message
 Post subject: equality check.
PostPosted: Thu Feb 15, 2007 1:48 pm 
Senior
Senior

Joined: Mon Jul 24, 2006 8:43 am
Posts: 160
Hi,
I add relationship to an entity persist it and then check that it has added and it fails.

The relationship is called children and it is on the entity Person.

The relationship in Person as:

private List <Person> children = new ArrayList();

@ManyToMany(cascade=CascadeType.REFRESH)
public List<Person> getChild() {
return children;
}

Here is my test code

Person person = new Person();
Person child = new Person();
List <Person> children = new ArrayList();
em.persist(person);
em.persist(child);

children.add(child);
person.setChildren(children);
em.getTransaction().commit();

// now reread and test
em.refresh(person);
System.out.println("will print true if equal, person.getChildren().equals(children));


and false is outputted even though the contents of both Lists are the same.

On inspection of the hibernate code, when .equals() is called it delegates to:

org.hibernate.collection.PersistentBag.equals()

which delegates to java.lang.Object, so only the object references are compared which then fail.

I would have thought since I declared the relationship as an ArrayList, the equality check should work the same way, i.e. checking contents.

This does not appear to be case,

Comments, thoughts welcomed...


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 15, 2007 8:28 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
check the wiki area for equals/hashCode implementation.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 16, 2007 1:38 pm 
Senior
Senior

Joined: Mon Jul 24, 2006 8:43 am
Posts: 160
emmanuel wrote:
check the wiki area for equals/hashCode implementation.

Thanks for that.
I checked the article and it is more to do with single entity not relationships.

I looked at the code for org.hibernate.collection.PersistentBag.equals() and it just delegates to java.lang.Object.
So because of this I would guess that it is irrelevant if the .equals() is implemented in the POJO.

What's interesting is that there is another equals commented out

/*public boolean equals(Object other) {
read();
return bag.equals(other);
}

public int hashCode(Object other) {
read();
return bag.hashCode();
}*/

Is there any plans to update PersistenceBag.equals()?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 20, 2007 7:22 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
interesting, that's a choice I have been arguing with Gavin when I joined Hibernate. As you can see I lost :-)

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 13, 2007 7:59 am 
Senior
Senior

Joined: Mon Jul 24, 2006 8:43 am
Posts: 160
Fair enough. I would think it should there of course :)


Top
 Profile  
 
 Post subject: Re:
PostPosted: Wed Nov 25, 2009 7:08 pm 
Beginner
Beginner

Joined: Sat Sep 17, 2005 6:50 am
Posts: 23
emmanuel wrote:
interesting, that's a choice I have been arguing with Gavin when I joined Hibernate. As you can see I lost :-)

emmanuel, I tried to locate your/Gavin arguments about why bag does not implement equals/hashCode as an ordinary collection here, but that is not evident for me. Is it worse opening a bug in JIRA?

Relative links:


Top
 Profile  
 
 Post subject: Re: equality check.
PostPosted: Thu Aug 30, 2012 11:35 am 
Newbie

Joined: Thu Jan 26, 2006 2:19 pm
Posts: 4
Pretty old topic, but it's at the top of the Google results for "hibernate persistentbag equals" so I thought I'd add my two cents and see if we can get a response/status update.

If PersistentBag implements the List interface, this is a bug. Plain and simple. A List is an ordered collection of objects and has a well defined equals operation. This unexpectedly fails that check.

If PersistentBag doesn't implement a List interface, feel free to implement equals by some other standard. I'd expect it to behave like a Set at that point, but I guess it would depend on implementation.


Top
 Profile  
 
 Post subject: Re: equality check.
PostPosted: Thu Aug 30, 2012 7:06 pm 
Beginner
Beginner

Joined: Sat Sep 17, 2005 6:50 am
Posts: 23
mressler wrote:
If PersistentBag implements the List interface, this is a bug.

Indeed, it does, otherwise Hibernate objects are not injectable into POJOs:
Code:
public class PersistentList extends AbstractPersistentCollection implements List

Feel free to vote for HHH-5409: even though the bug is very old, nobody (except real gurus) really cares.


Top
 Profile  
 
 Post subject: Re: equality check.
PostPosted: Thu Aug 30, 2012 7:32 pm 
Newbie

Joined: Thu Jan 26, 2006 2:19 pm
Posts: 4
Link for the lazy:

https://hibernate.onjira.com/browse/HHH-5409

This seems like some low-hanging fruit that would have saved me (and surely others) some headache.


Top
 Profile  
 
 Post subject: Re: equality check.
PostPosted: Tue Oct 02, 2012 1:39 am 
Newbie

Joined: Tue Oct 02, 2012 1:32 am
Posts: 1
mressler wrote:
Link for the lazy:

https://hibernate.onjira.com/browse/HHH-5409

This seems like some low-hanging fruit that would have saved me (and surely others) some headache.


Hey dude.. I wanna check this link, but it can't open..Recheck it.

_________________
shire


Top
 Profile  
 
 Post subject: Re: equality check.
PostPosted: Tue Oct 02, 2012 3:34 am 
Beginner
Beginner

Joined: Sat Sep 17, 2005 6:50 am
Posts: 23
shire5555 wrote:
Hey dude.. I wanna check this link, but it can't open..Recheck it.

The link opens just fine. Try again, perhaps temporary internet problems.


Top
 Profile  
 
 Post subject: Re: equality check.
PostPosted: Fri Sep 23, 2016 4:02 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1383
Why would you want to include a List in a equals/hashCode comparison for a root entity? This is a wrong approach.

Equality should be based on the underlying table record unicity constraint. Ideally, you should have a natural key in every database table like a SSN, email address, domain name, UUID.

Sometimes, you don't have a natural id, but then you still have the primary key. Contrary to popular belief, you can use the PK for equals/hashCode, you just have to make sure that hashCode renders a constant value for every entity state transition.

If you worry about hashCode performance, then you should know that a persistent collection is not meant to store large amounts of data. So, prior to having the hashCode as a real bottleneck (as depicted in Effective Java), you'd have to fetch the collection, and the fetching tons of data is way more costly anyway. If that's the case, you are better off using a query instead.

_________________
If you liked my answer, you are going to love my High-Performance Java Persistence book and my blog as well.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 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.