Nemi
Nemi

Reputation: 3061

Hibernate: best collection type to use - bag, idbag, set, list, map

I am looking for what most people use as their collection type when making one-to-many associations in Hibernate. The legacy application I am maintaining uses bags exclusively, but keeps them as lists in code. The tables associated have an id field, so an idbag seems more appropriate, but documentation recommends a Set.

EDIT: I mistakenly referenced that the documentation recommends a set. In reality, the official documentation is equally vague on all collection types. What I find is that some websites seem to infer that Set is the most common, and the Hibernate book I am reading explicitly says this about sets:

This is the most common persistent collection in a typical Hibernate application. (see: page 242 of 'Java Persistence with Hibernate' by Christian Bauer and Gavin King)

I guess that is what threw me and made me seek out what others are using.

EDIT2: note that Gavin King is the creator of Hibernate

Upvotes: 12

Views: 20887

Answers (4)

Cookalino
Cookalino

Reputation: 1619

Based on the experience of using both I would recommend using a List. If you are getting data out of the database and displaying / manipulating it then it nearly always needs to be kept in a consistent order. You can use SortedSet but that can add a whole world of pain (overriding equals, hashcode etc. and sorting in different ways) compared to just adding an order by and storing it in a List. Lists are easier to manipulate - if a user deletes line 3 on the page, then just remove item 3 in the List. Working with a Set seems to involve lots of unnecessary code and messing about with iterators.

When I have used Sets with Hibernate I have frequently found myself ripping all the Sets out after a few weeks and replacing with Lists because Sets are giving me too many limitations.

The Hibernate documentation and third party tools seem to use Sets by default but from hard experience I have found it much more productive to use Lists.

Upvotes: 12

MrWhite
MrWhite

Reputation: 193

I would recommend using a set because a set is defined as a collection of unique items and thats normally what you deal with.

And .iterator().next() is save when there is no element in your collection.

.get(0) might throw an IndexOutOfBoundsException if you access an empty list.

Upvotes: 2

Nemi
Nemi

Reputation: 3061

Ok, after quite some time I have found a reason NOT to use a Set as a collection type. Due to problems with the hashcode/equals overrides and the way hibernate persists, using any java API functionality that calls hashcode/equals is a bad idea. There is no good way to consistently compare objects pre- and post-persistence. Stick with collections that do not rely on equals/hashcode like bag.

More info here:

http://community.jboss.org/wiki/EqualsandHashCode (this link makes it sound like a business key is the way to go, but read the next link fully to see why that is not always a good idea)

https://forum.hibernate.org/viewtopic.php?f=1&t=928172 (read the whole discussion to make your head spin)

Upvotes: 9

ChssPly76
ChssPly76

Reputation: 100746

I'm guessing people use all kinds of things :-) - different collection types serve different purposes so the "best" one depends on what you need it for.

That said, using List in code is usually more convenient than using Set even though said List is unordered. If nothing else, '.get(0)' is easier on the eyes than .iterator().next() :-) Hibernate bag support is definitely adequate for this purpose plus you can even add an order-by declaration (if applicable) and have your list sorted.

idbag is a whole different animal used for many-to-many associations; you can't really compare it to regular Set or List.

Upvotes: 5

Related Questions