Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Hibernate is ultra-sensible at collections!

 
Cristian Vrabie
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Found (another) tricky thing about Hibernate.

To be honestly is starting to piss me off. Maybe because I still don't have the experience to steer clear of these problems or i just miss the old days when I was writing every query with my own hand and everything that happened was so predictable.

So I have a standard class A that in the hbm mapping has a bag of objects B. I wanted to use bag because they say everywhere that bags are very efficient. However in my class i use a HashMap to store the B objects so it's easier to manage them. The key of the map is a property from the B object itself.

To make the conversion i use a trick in the setter/getter:



This seems not to be on the liking of Hibernate, and a simple get to an object A seems to trigger an update in the database.



My guess is that before the session closing, a is checked for modifications and the hash code in A.getObjs() is obviously different than when hibernate originally put it there, even thow the same items are in the collection, this triggering an update.

Is this right?

[ November 26, 2008: Message edited by: Cristian Vrabie ]
[ November 26, 2008: Message edited by: Cristian Vrabie ]
 
Paul Sturrock
Bartender
Posts: 10336
Eclipse IDE Hibernate Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I wanted to use bag because they say everywhere that bags are very efficient

Do they? Be aware that this is only true if your association is bi-directional.From the Hibernate documentation:

Bags are the worst case. Since a bag permits duplicate element values and has no index column, no primary key may be defined. Hibernate has no way of distinguishing between duplicate rows. Hibernate resolves this problem by completely removing (in a single DELETE) and recreating the collection whenever it changes. This might be very inefficient.

....

Just before you ditch bags forever, there is a particular case in which bags (and also lists) are much more performant than sets. For a collection with inverse="true" (the standard bidirectional one-to-many relationship idiom, for example) we can add elements to a bag or list without needing to initialize (fetch) the bag elements! This is because Collection.add() or Collection.addAll() must always return true for a bag or List (unlike a Set). This can make the following common code much faster.




However in my class i use a HashMap to store the B objects so it's easier to manage them

I'm not sure I follow. Does this mean that you have code expecting a Map returned from your "public Collection<B> getObjs()" method? Doesn't this limit your code?
 
Cristian Vrabie
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ah. It seems they updated the bags from the last time i looked. Hmm.. this changes things. I think I'll be ditching bags.

I'm not sure I follow. Does this mean that you have code expecting a Map returned from your "public Collection<B> getObjs()" method? Doesn't this limit your code?

Not really. I was just using the map for operations on it inside the class A. Other classes would only access the get/set of A and would expect a collection.
 
Cristian Vrabie
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Paul! I must remember to get in touch with reality from time to time )
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic