-->
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.  [ 37 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: "Don't Let Hibernate Steal Your Identity"
PostPosted: Mon Nov 13, 2006 1:41 pm 
Newbie

Joined: Fri Mar 11, 2005 11:18 am
Posts: 8
I read an article at

http://www.onjava.com/pub/a/onjava/2006 ... tml?page=1

and I am courious about your opinions about this.

Regards
Sergiu.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 13, 2006 1:52 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Incomplete, misleading, wrong conclusion.

Not a single time does the author mention Hibernate's persistence context, or the object identity guarantee it provides. Not once does the author mention object states, and that object identity is very much dependent on the the state an object is in. There is nothing in this article that explains how an application that never compares instances in detached state does not need a custom object equality routine.

http://www.manning.com/bauer2


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 13, 2006 1:59 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
We have clearly explained (several years ago now) how to handle these issues in HiA and JPwH. (Which this author does not seem to have read.) You don't need to avoid use of surrogate keys, you merely need to identify natural keys, and use them in your equals/hashCode methods. This article, IMO, did not merit publication in onjava.com.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 13, 2006 2:06 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Finally, it's surprising and amazing how few Java developers really know what object identity and equality are about.

Every OO language basically has the same concept, a built-in identity strategy (== in Java) for instance comparison, and a custom overridable construct (equals() method). Sure enough, if the built-in strategy does not satisfy the identity/equality requirements in a particular scenario, you have to write and use a custom routine.

Hibernate even _helps_ you with this when you require "one in-memory instance per database row", with it's freely extendable persistence and identity context. An article that says that "Hibernate steals your identity" can't be more wrong.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 13, 2006 10:21 pm 
Newbie

Joined: Tue Nov 07, 2006 5:06 pm
Posts: 13
I recently ran into a problem with hashCode & equals while attempting to follow HIA's suggestions. I have a simple 'Contact' class that has first-name, last-name, and phone columns. After reading the HIA section on hashCode & equals I used the combination of all these columns as the key. Sure enough this blew up when I tried to update a detached instance (the requirements call for the user to have editing ability for all these fields). When updating the collection, it couldn't find the instance in the snapshot, so thought it was new and created an insert statement (which subsequently caused a primary-key constraint violation).

I'm certainly not blaming HIA for this; it states clearly "Instances from different sessions are no longer equal if one is modified...". But my circumstance violates the business-key equality propounded by the book. The user must be able to edit any field.

Is there an elegant solution to this?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 14, 2006 3:23 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
How do users identifty your Contact instances, when they look at the screen? How can they say "this one is different than this one!" without referring to the non-visible surrogate primary key?

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


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 14, 2006 11:48 am 
Newbie

Joined: Tue Nov 07, 2006 5:06 pm
Posts: 13
They can't really, at least not in some discernable way that could be modeled consistently programmatically. One can create a contact John Smith 555-555-5555 and change it to Bob Jones 444-444-4444. In reality this will probably never happen, but reasons for changing the phone number aren't hard to come by, the last name could be for marriage, and (who knows) maybe the user got the contact's first name spelled wrong or something. When I first created the key I figured the combination of all fields should at least be unique, but by using that method changing any field changes the record's identity.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 14, 2006 12:38 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
So use an extended persistence context that scopes database identity across that conversation. This is a Hibernate feature.

Without Hibernate, you wouldn't even have that and would have to do some surrogate global unique key hack (like in the article).

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


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 14, 2006 1:35 pm 
Newbie

Joined: Tue Nov 07, 2006 5:06 pm
Posts: 13
Thanks for your replies; this is definitely an interesting subject. Can you point me to some information about using an extended persistence context like this? Like I mentioned, I have the HiA book, but not JPwH yet.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 14, 2006 2:17 pm 
Newbie

Joined: Tue Nov 07, 2006 5:06 pm
Posts: 13
I think you have eluded to Hibernate's ability to overcome the problems outlined in the article, but I'm curious as to why you're opposed to it. It seems like a simple solution to the problem.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 14, 2006 2:20 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Like I said, the article is incomplete and misleading. Because the outlined "solution" is neither a) Hibernate related b) the best c) the primary choice.

Read JPwH.

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


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 14, 2006 7:31 pm 
Newbie

Joined: Tue Nov 07, 2006 5:06 pm
Posts: 13
Ok, well thanks for the info.


Top
 Profile  
 
 Post subject: what if .equals() has more than one use?
PostPosted: Thu Dec 07, 2006 6:20 pm 
Beginner
Beginner

Joined: Thu Feb 26, 2004 11:45 am
Posts: 46
I ran into a problem in our shop, as relates to this. I'm sure somebody will correct me on this.

Hibernate suggests using business keys for equality, so that it can properly identify it's "identity", that is, roughly what row in the database the object represents.

A person with ID, Name, Address, Phone, nickname, whatever might be identified with a business key of just Name, and maybe Address if that isn't likely to change, if i understand the notion of a business key correctly. Fair enough.

In this way, 2 instances of this object with only a different nickname will appear to be the same object, because it's not included in the business key and equals() returns true.

I get all that, and i get why it's needed.

Problem i ran into is in our GUI/Swing portion of our application. They also use equals(). They use it to indicate a change to the entity took place, so a new view can be rendered. In their case, they need to know the above 2 instances are NOT equal, so that the correct listeners are fired and the new object replaces the old, and the nickname will be displayed.

So, we have these 2 objects. Pesistence needs these 2 objects to be equal, the GUI needs these two object to be !equal.

Caused a real rumble in our group. Both seem very reasonable.

The point i'm making is simply the choice of overriding and using .equals(). Clearly there can be many other application contexts that rely on .equals() to work in a slightly different way.

I don't have any answers to this, but since i haven't heard anybody complain about it, i'm wondering if i'm missing something real obvious or am overanalyzing it or something. Any thoughts?

FWIW, i suggested it was a problem they needed to solve - i guess they figured something out.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 11, 2007 6:48 am 
Newbie

Joined: Fri Aug 04, 2006 6:09 am
Posts: 18
Hi,

i'll put my hand up and say that I am one of those java developers who don't quite get all the intricacies of equals() and hashcode().

I have read the article mentioned in this thread as well as the FAQ entry on this site. I'm still confused when I might have a problem.

I'd be grateful if someone could help me with some high-level guidelines. Here's my currrent approach:

I have designed most of my entities as using an oracle sequence (one per entity).

As soon as I have an entity thats going to be part of a Set() I stop using the above id strategy and instead switch to manually assigning a key - a class is used which wraps the oracle sequence but hibernate thinks the app is generating it.

I think I also need to implement hashcode and equals to use this new identifier?

What is wrong with this method?

Cheers

R


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 11, 2007 2:54 pm 
Newbie

Joined: Mon May 29, 2006 5:39 pm
Posts: 6
Hi Christian and Gavin,

As the author of the mentioned article, I'd very much like to know what the objections are to the discussed technique. Name calling aside, there wasn't really any mention of any problems with the technique.

I understand that Hibernate provides solutions to these issues, but Hibernate is very flexible and can accommodate several different techniques. Most of these solutions involve some compromise, so making different solutions available seems like a good idea. The technique I suggested has different strengths and weaknesses than the one in the documentation, and should be considered as a valid choice. Whether it's the right choice for a project depends on the requirements. This was clearly stated in the article.

Perhaps the attempt at a catchy title offended you and you began reading the article with a negative impression already. If so I apologize, my intent was certainly not the criticize the Hibernate framework. Quite to the contrary, I've be using it for some time (along with the described technique for identity) and am very pleased. My point was that Hibernate does not have to manage the assigning of database primary keys. It can, but there are other alternatives that work with Hibernate quite well (a testament to how flexible the framework is). My only suggestion is that these be mentioned in the documentation so that users have a choice.

If there is a problem with using an application-generated id for both the database primary key and for object identity, I'm very interested to hear what it is. So far this thread has not mentioned anything.

Disagreements aside, thanks for providing a excellent persistence framework. I work with Hibernate every day.

James Brundege


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 37 posts ]  Go to page 1, 2, 3  Next

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.