-->
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.  [ 8 posts ] 
Author Message
 Post subject: Proxies with hashCode() and equals()
PostPosted: Thu May 13, 2004 9:51 pm 
Beginner
Beginner

Joined: Wed Oct 01, 2003 11:01 pm
Posts: 23
Chapter 14.2 from the reference manual states:


Quote:
Certain operations do not require proxy initialization
  • equals(), if the persistent class does not override equals()
  • hashCode(), if the persistent class does not override hashCode()
  • The identifier getter method
Hibernate will detect persistent classes that override equals() or hashCode().


My equals and hashCode only uses the the identifier, so there's no need for the proxy to be initialized. Is there a way to tell Hibernate this? Or will Hibernate initialize the proxy anyway for equals() and hashCode() (in which case is this a good candidate for a feature request)?


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 14, 2004 4:30 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
A class using the database identifier in equals() is possibly broken. See this page (yes, its a mess): http://www.hibernate.org/109.html

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


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 17, 2004 11:29 pm 
Beginner
Beginner

Joined: Wed Oct 01, 2003 11:01 pm
Posts: 23
christian wrote:
A class using the database identifier in equals() is possibly broken. See this page (yes, its a mess): http://www.hibernate.org/109.html


Yeah, I've seen that page, along with the looong thread linked at the bottom.

For my application, I'm content to enforce database row equality (hence using the PK in equals()) across the board. Given this, is my original request viable?


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 18, 2004 1:10 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Your code is broken anyway if you use the database identifier in equals().

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


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 18, 2004 10:07 pm 
Beginner
Beginner

Joined: Wed Oct 01, 2003 11:01 pm
Posts: 23
christian wrote:
Your code is broken anyway if you use the database identifier in equals().

You know, sometimes I just can't figure out if you're trolling or serious. Can you explain why you say this? Obviously I disagree with you here. In fact, the page you pointed out clearly states that this is a viable option:
Quote:
If you use manually assigned ids (eg the "assigned" generator), you are not in trouble at all, you just have to make sure to set the id before adding the object to the set.


You may not think this is a good idea, but I can assure you that my code is not broken. It works as I expect it to, and all I'm after now is to see if I can avoid proxy initialization. The proxy problem has discussed at length in http://forum.hibernate.org/viewtopic.php?t=928172, so I know I'm not alone here.

So back to my original question: would it be difficult to tell Hibernate to not initialize a proxy for a class that overrides equals() and hashCode() because it simply uses the PK? I'd imagine this should be simple, but I don't know enough about proxies/cglib to check myself.


Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 19, 2004 12:04 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Not sure if I can make it any clearer than all the resources you say you have already seen, but here it goes (maybe I can at least make it more condensed):

The issue has to do not so much with the entity itself defining equals/hashCode. Its more a problem of those entities which do define an equals/hashCode being included in a hash-based collection (such as sets and certain map implementations). The contract for those collection interfaces state that the value used to determine placement of the object within the given collection cannot change while the instance is contained in the collection. This is not a Hibernate requirement, these are contracts defined on those standard java collection interfaces; Hibernate simply magnifies it because if you use the db id as the basis for the hash-code (which logic makes the most sense) then you've just broken this contract if the id is assigned to an instance while that instance is included in such a collection.

Visualize what happens when you do this...
1) You load an entity of type A from the session; this entity has a set of entities of type B (assume the Set of Bs is marked with cascade all);
2) You then instantiate a new B and set its values;
3) You add this new B to the loaded A's set of Bs (at this point the Set impl calculates the internal storage position of that newly added B based on the hashCode() method)
4) You flush the session, at which time Hibernate will attempt to save the new B instance through its cascading association to A; here Hibernate or the DB generates the ID value and sets it on the B instance. At this point the contract with the Set interface has just been broken (assuming the hasCode() value is based on the PK).

Quote:
If you use manually assigned ids (eg the "assigned" generator), you are not in trouble at all, you just have to make sure to set the id before adding the object to the set.

Hopefully you'll undertand why that above statement is true given the explanation of the issue...


And no, currently there is no way to tell Hibernate to not initialize a proxy on equals() and/or hashCode() invocation.


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 19, 2004 4:50 am 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
Use some custom utility:

Quote:
PersistentObjects.equals(obj1,obj2);

and "handles" for collections:
Quote:
// wrappers for maps and collections must be a better way
map.add( PersistentObjectHandle(obj1), value );

It must not be very complicated to implement this custom API.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 20, 2004 9:20 pm 
Beginner
Beginner

Joined: Wed Oct 01, 2003 11:01 pm
Posts: 23
steve wrote:
The issue has to do not so much with the entity itself defining equals/hashCode. Its more a problem of those entities which do define an equals/hashCode being included in a hash-based collection (such as sets and certain map implementations).


Steve,

I think you're misunderstanding what I'm asking for. I fully understand the implications of using assigned identifiers. I don't have any problems with equals()/hashCode() and hash-based collections.

My issue is with when Hibernate initializes proxies. Right now, it intializes proxies on equals()/hashCode() invocation only if the persistent object overrides them.

As you noted, there's no way to do so right now.

I'm just wondering how hard it would be to make this user-configurable so that I can tell Hibernate not to initialize a proxy until a persistent property is accessed.


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