-->
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 Previous  1, 2, 3  Next
Author Message
 Post subject:
PostPosted: Thu Jan 11, 2007 3:36 pm 
Regular
Regular

Joined: Wed Dec 07, 2005 4:19 pm
Posts: 53
I know this is a water under the bridge...

...but there would have been less confusion had Hibernate required presistent objects to implement some sort of "Identity" interface. The issue is very well documented (thanks, Gavin & Christian), but regrettably, using equals() to implement Hibernate 'identity' is creating hosts of other issues (not to mention confusion of people with C++ background where equality operator was commonly implemented as 'equality by value').

I assume the goal has been using POJO without any changes; unfortunately the (often necessary) change to equals() implementation is intrusive.

That said and beeing long ago, Hibernate requires far more than changing your equals() operators. You should re-think your application design from the grounds up - and realizing that your data model (objects) is now a different animal.
Of course, you get so much from Hibernate that re-thinking is definitely worth it (not to mention the challenges of learning Hibernate :-)).

(Just as one isolated example, you must now be carefull about putting your 'immediate, transient' data values into such objects - because your session (auto) flush can commit such data prior to the time _you_ wanted to commit them --- and there are many, many more issues).


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 12, 2007 12:52 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
jyx34 wrote:
Whether it's the right choice for a project depends on the requirements. This was clearly stated in the article.


What is not in the article are the other, better and preferred options.

Quote:
Perhaps the attempt at a catchy title offended you and you began reading the article with a negative impression already.


No, the content of the article is the issue, not the title. On the other hand, it's not the first time mediocre content is hidden behind a catchy title with "Hibernate" in it.

Quote:
My point was that Hibernate does not have to manage the assigning of database primary keys.


The assignment of primary keys has _nothing_ to do with the object identity scope guarantee of a persistence service. You should read at least one of the books we wrote, or maybe the Hibernate reference and some Wiki documents.

Quote:
My only suggestion is that these be mentioned in the documentation so that users have a choice.


People need to read the already available documentation first and understand what options they have. Your hack is maybe the last option in a quite long list.

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


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 12, 2007 12:53 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
mbrunecky wrote:
I know this is a water under the bridge...


Hibernate _does not_ require any of the things you think it does, your conclusions about equals, flushing, etc. are not correct. Please, read some book.

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


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 12, 2007 3:27 am 
Newbie

Joined: Mon May 29, 2006 5:39 pm
Posts: 6
Ok, let's try again. I'm really trying to glean some useful information from this discussion, though the posts seem rich in insults but poor in information.

My "hack" as you call it is simply this:
Let the application assign the ids.

This is an obvious and old idea certainly not invented anytime recently. It obviously works and it works with Hibernate because Hibernate is specifically designed to handle this situation. There is also a clear drawback: if you use UUIDs the ids are long Strings, which take up a lot of database space and may be somewhat slower. This limits which applications can benefit from this, but there is a subset of applications in which this isn't an issue.

Yes there's lots of other ways to handle identity, depending on what constraints the app has. But there are lots of tricky issues, and the application developers have to think carefully all the time about how they're using the objects lest they introduce a subtle bug.

Letting the application assign the ids is easy, and it's really hard to screw up. These are good things.

However, it's clear you hate application-assigned ids. What's not clear is why. Saying "because other techniques are better" or "read the book" is not informative. Tell us the specific disadvantages of application-assigned ids (other than that mentioned above).

James

PS Of course I've read HiA as well as the online documentation (JPwH wasn't published when I wrote the article). If you think there's an explanation in either HiA or the online docs of why application-assigned ids are bad, give us the quote and the link/page. I'd really like to see it!
[/i]


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 12, 2007 4:09 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Repeat: When and how primary key values are assigned DOES NOT INFLUENCE how the identity map of a persistence service works. Hibernate has a flexible identity map (the Session). If you use it right, you don't need to implement your own identity mapping (equals() method). Again, nothing to do with how and when primary key values are assigned.

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


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 12, 2007 5:21 am 
Newbie

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

your statement above seems to contradict the WIKI (http://www.hibernate.org/109.html):

Quote:
If you use manually assigned ids (e.g. the "assigned" generator), you are not in trouble at all, you just have to make sure to set the identifier value before adding the object to the Set. This is, on the other hand, quite difficult to guarantee in most applications.


I have taken this literally to mean if the app assigns ids then the problem goes away.

Is this incorrect?

R


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 12, 2007 5:43 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
The problem of the difficult equals() implementation goes away! If you use the identity map right, you never have to implement equals().

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


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 12, 2007 1:46 pm 
Regular
Regular

Joined: Wed Dec 07, 2005 4:19 pm
Posts: 53
christian wrote:
The problem of the difficult equals() implementation goes away! If you use the identity map right, you never have to implement equals().


Java Persistence with Hibernate, page 395 (bottom):
Quote:
Whenever you work with objects in detached state, and especially if you test them for eqality (usually in hash-based collections), you need to supply your own implementation of the equals() and hashCode() methods for your persistent classes.

So ... which one is true?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 12, 2007 1:52 pm 
Senior
Senior

Joined: Sun Jun 04, 2006 1:58 am
Posts: 136
mbrunecky wrote:
christian wrote:
The problem of the difficult equals() implementation goes away! If you use the identity map right, you never have to implement equals().


Java Persistence with Hibernate, page 395 (bottom):
Quote:
Whenever you work with objects in detached state, and especially if you test them for eqality (usually in hash-based collections), you need to supply your own implementation of the equals() and hashCode() methods for your persistent classes.

So ... which one is true?


may be

*identity map right* == extendended persistence context....

so the second case does not fall under *identity map right* i guess :)

_________________
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 12, 2007 4:06 pm 
Newbie

Joined: Mon May 29, 2006 5:39 pm
Posts: 6
christian wrote:
The problem of the difficult equals() implementation goes away! If you use the identity map right, you never have to implement equals().


You're now suggesting not to implement equals!? The Hibernate documentation recommends overriding equals() and hashCode() if you're using detached objects, as you're repeated numerous times yourself. In fact, you override these methods in your swingdemo app.

You say you should do this quite clearly here:
http://forum.hibernate.org/viewtopic.php?t=928172&postdays=0&postorder=asc&start=75

and here:
http://forum.hibernate.org/viewtopic.php?t=928172&postdays=0&postorder=asc&start=90

It says it in the wiki page on this topic:
http://www.hibernate.org/109.html

It says it VERY clearly in the online documentation:
http://www.hibernate.org/hib_docs/v3/re ... lshashcode

It weakly suggests it may be necessary in HiA:
HiA page 122

And apparently says it clearly in JPwH (previous post).

It seems clear from the documentation that you often do want to override equals. Also, Hibernate is not the only thing that uses equals. Collections use it. Sometimes algorithms use it.

We know there are problems with object identity when objects are persisted. These are not in any way specific to Hibernate, this is true of all persistence frameworks.

It seems to me there are basically 3 ways to implement equals:
1) don't override equals, so if a.equals(b) then a==b
Pros: simple, requires no extra coding
Cons: if you have detached objects in Sets, you have to be very careful not to get a duplicate object from a different Session into the same Set.

2) use a business key to define equals
Pros: solves the above problems, allows you to use simple, Hibernate-managed ids, this is the Hibernate-recommended approach with detached objects that use Sets.
Cons: good business keys may be hard to find due to the changability of most fields, especially when every field in a table is editable from within the app. Requires careful custom coding for each model object.

3) use application-assigned ids (assumes UUIDs to avoid id collisions)
Pros: solves all of the problems from the above 2 approaches.
Cons: uses a longer, slower character-based primary key that inflates database size. Not suitable for large tables, especially if there are lots of foreign keys.

The current documentation only mentions 1 and 2. Both of these have strengths and weaknesses. I've added 3, which also has strengths and weakness as listed above. It works just fine if the size of the ids is not problem. It's very simple to implement and very hard to break. Application developers still have to be careful with their object graphs, but some of the pitfalls are avoided so they spend less time thinking about the persistence framework.

All 3 are viable choices. All 3 have tradeoffs. People should carefully choose which approach fits their application. What's the problem?


BTW, just to clarify I in no way thought of this idea, I just use it. It goes way back, and has been mentioned many times in these forums. In particular there are several references to this idea in the comments of the wiki equals page:
http://www.hibernate.org/109.html


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 12, 2007 4:35 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
So don't use detached objects if the equals() implementation bothers you. Let me translate my quotes you quoted.

Christian: "Detached Objects don't work well if you can't find a business key for equals."

(This means: Don't use detached objects if you don't want to.)

Christian: "This is certainly not the recommended approach and I'd be interested where you found such a statement. You should implement euqals/hashcode if you'd like to use your domain objects outside of a session (mix them in a Set, probably)."

(This means: Don't use detached objects if you don't want to.)

Reference documentation: "Hibernate guarantees equivalence of persistent identity (database row) and Java identity only inside a particular session scope."

(This means: Don't use detached objects if you don't want to.)

Do you now understand that overriding equals(), and your hack to make it work with GUIDs, is optional? That there is a another, better and easier option? We could continue this game and I could give you a few more of the same quotes from other sources...

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


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 12, 2007 4:44 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
By the way, I fully understand what you want... In practice the Hibernate identity map, and very very rarely an equals() implementation based on a business key, are completely sufficient.

If you read the thread carefully from the beginning, the only case that was identified when this is not sufficient is a scenario in which the application could not take advantage of the Hibernate identity map. Maybe because the application designer didn't know about it, maybe because he read the wrong article. Then he could "fix" it with your GUID equals() method and detached objects. That still doesn't mean that this strategy has to be in the reference documentation. And it's not "Hibernate stealing your identity."

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


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 12, 2007 6:18 pm 
Newbie

Joined: Mon May 29, 2006 5:39 pm
Posts: 6
What you seem to be saying is: most projects don't need to override equals because most projects don't need to use detached objects. This is simply not my experience. Most projects I've seen use detached objects. Perhaps you're arguing this is a mistake.

So in effect there are two issues:
1) Should you use detached objects or not? If not you don't need to override equals. If so...
2) For projects with detached objects: what are your options for implementing equals?

My position was only considering issue 2. That is, it was only applicable to projects with detached objects. If this wasn't clear, it definitely should have been.

Are you suggesting that too many projects use detached objects when they shouldn't?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 13, 2007 12:21 am 
Senior
Senior

Joined: Sun Jun 04, 2006 1:58 am
Posts: 136
jyx34 wrote:
Are you suggesting that too many projects use detached objects when they shouldn't?

.
I am curious what christian has to say about that ...

We use detached session(s) in our desktop gui app and we had to resort to *hack* mentioned in the original article as we could not identify immutable business keys for all the tables...

We were using long running session at one point but we had different set of problems with that..

_________________
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 13, 2007 4:14 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Yes, I am saying that too many projects use detached objects... That's why I have been saying "Have a look at the alternative, the extended persistence and identity context" for a few years. And I've been saying it about 20 times now in this thread.

_________________
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.  [ 37 posts ]  Go to page Previous  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.