Search This Blog

Wednesday, 12 October 2011

Hibernate And Collections Support

Hibernate supports the use of Collections in the Java model objects. Associations between tables are represented using these collections.
e.g.: If there is a one-to-many relation between owner and pet (1 Owner has many pets) then a collection of pets can be mapped in the Owner class.
class Owner {
    private List<Pet> pets = new ArrayList<Pet>();
}
Some simple recommendations that I have come across when implementing collections is (Java Persistence With Hibernate Book):
  1. Use an Interface to declare the type of the property and not the implementation class.
  2. Initialize the collection with the correct implementation at the point where you have declared the property. (Like the above example). Don't leave that code for constructors or methods
  3. If possible then code with generics.It leads to better readability.
The different collections supported by Hibernate are:

Collection Type Implementation Details When To Use
java.util.Set Initialize the collection with a java.util.HashSet When you don't want any duplicates, and the ordering does not matter.
java.util.
SortedSet
Initialize the collection with a java.util.TreeSet and provide settings for specifying the sorting When you don't want any duplicates, but the ordering does matter.
java.util.List Initialize the collection with a java.util.ArrayList When the position of the elements matters.
java.util.
Collection
Initialize the collection with a java.util.ArrayList along with the bag/idbag settings When duplicates are OK and ordering of elements is immaterial
java.util.Map Initialize the collection with a java.util.HashMap When key value pairs are needed
java.util.
SortedMap
Initialize the collection with a java.util.TreeMap and
provide settings for specifying the sorting
When key value pairs are needed and the ordering matters

Hibernate also provides with the ability to create custom collections.This can be done by implementing PersistentSet, PersistentBag, PersistentCollection ,PersistentMap or PersistentList classes. 

In the next posts we shall try using these varied collections.

6 comments:

  1. Thanks, exactly what i was looking for! Simple and useful.

    ReplyDelete
  2. a newbie here , wanted to ask a basic ques ... as you said "Hibernate also provides with the ability to create custom collections.This can be done by implementing PersistentSet," ... why not implement the java.util.Set ?? whats difference in above two??

    ReplyDelete
  3. Hi,
    If you check the documentation for PersistentSet you will observe that this interface extends the Set interface. So Hibernate's custom implementations are also an instance of java.util.Set.
    The reason for this specialized interface is the way Hibernate handles collections. In most cases collections are loaded lazily. So Hibernate needs some hook methods that can allow it to intercept the calls to the set methods and do certain operations such as loading the collection data from the database.
    This was one case, there are other scenarios where Hibernate needs a certain level of control over the set, which is not available in the default implementations.
    Hence the need for an extended interface and custom implementations.
    Hope this helps.

    ReplyDelete
  4. Talking of point 2 "Initialize the collection ... Don't leave that code for constructors or methods"
    Suppose you have Student having a set of books. now the calling code ( which will insert the Student & books in DB table ) will be something like
    Set Books = new HashSet();
    Books.add(b1)
    Books.add(b2)
    Student s1 = new Student();
    s1.setBooks(Books);

    The above code will work irrespective if we "Initialize the collection" or not inside the Student class ... BUT it has to be initialized by the calling code so wondering why is point 2 above stating otherwise

    ReplyDelete
  5. Yes, the code will work. The second point is actually a recommendation (a best practice) I think it has more to do with the way proxy creation is done in Hibernate.
    A better way (if we go by the above recommendation) to add books would be to use
    s1.getBooks.add() methods.
    When you use a setter method to set the collection, Hibernate has to perform some additional work to wrap your passed collection with a Persistent Set implementation.
    Having the collections specified at object instantiation allows Hibernate to do its magic at the earliest and then use that same collection wrapper ( generated during object creation) to manage your collections.

    ReplyDelete