Apr 15

An object by itself is intensely uninteresting.Objects contribute to the behavior of a system by collaborating with one another.One of relationship aspects between Objects can be represented by Association.

When we bring in Cardinality in Association we get One-to-One, One-to-Many and Many-to-Many.In later two One-to-Many and Many-to-Many we use Collection to represent many Side.For example: An Order have many OrderDetail’s.

We have these associations represented in Relational DBMS using foreign keys.So from any O-R framework we expect that to take care of these associations in smartest way possible.As these can easily become a performance bottle neck for the application.Some time you may end up loading lot of Data into memory, and sad part is you are never going to use them. 

So here is what i think we expect from Collections in O-R:

1. Ability to map the Collections to DB

2. Ability to Load them

3. Ability to traverse smartly

4. Ability to add elements to  collection

5. Ability to remove elements from collection

Some points from above I will try to explain in detail from Hibernate Perspective.I will be skipping mapping part that is well explained in Hibernate Reference Documentation.

Let’s start with which collections we generally want to map :

1. Set

2. List

3. Map

there could be special cases where we want to preserve Order (which can be insertion or sort)

1. SortedSet

2. LinkedList

3. SortedMap

One other kind of collection can be an array.But generally we dont use them in our domain models.Well there are reasons from O-R point also against them like lazy-loading,optimized dirty checking cannot be achieved as we cannot wrap them or byte code instrument them.

Collections and Hibernate

Persistent collections are treated as value objects by Hibernate. ie. they have no independent existence beyond the object holding a reference to them. Unlike instances of entity classes, they are automatically deleted when unreferenced and automatically become persistent when held by a persistent object. Collections can be passed between different objects (change “roles”) and this might cause their elements to move from one database table to another.

Hibernate “wraps” a java collection in an instance of PersistentCollection. This mechanism is designed to support tracking of changes to the collection’s persistent state and lazy instantiation of collection elements. The downside is that only certain abstract collection types are supported and any extra semantics are lost. Now before jumping in PersistentCollection code lets try to think what do we need this wrapper to do:

Lazy Loading

          It need to load actual data only “when” needed. So what is this “when”

                  a.) Doing  size() operation and isEmpty Check

                            Whenever this operation will be invoked PersistentCollection will check if collection has been loaded or not.If not then it will have another check whether this collection has been mapped as extra-lazy or not. If its extra-lazy then it will only do a “select count”  sql to get the size rather then loading the collection. If its not marked extra-lazy then it will load the collection from database and execute operation on actual collection.

                 b.) Doing a contains check

                          For this operation also we need to check whether Collection has been loaded or not. If its not loaded and marked extra-lazy then it will do a “select 1 ” to find out whether this element exists or not.So this will save us loading of the collection and a simple sql will suffice.If its not marked extra-lazy then it will load the collection and execute operation on actual collection.

                  c.) Getting iterator                  

                         For this operation no matter whether its marked extra-lazy or not it will need to initialize the collection from DB. But here it cannot return iterator of actual Collection.It will create a proxy Iterator.As it will need to keep track of remove operation on iterator.

                  d.) Adding some element in collection

                       This operation will have different implementations based on whether we are having a List or Set. As Set cannot allow duplicates. So question finally boils down on can we do an add without loading the collection. Well yes for List we can do that.But for Set we need to do a contains check internally, whether that element already exists or not which is similar to contains check i described above. 

                       If collection is loaded then we can directly do add on the collection and mark the collection dirty. Otherwise it queues the operation to be synced with DB at later stage. Again some kind of lazy behavior. Hibernate calls these operations DelayedOperations and execute them immediatedly after loading the collection whenever its is loaded.

                  e.) Removing some element from collection

                      This opertaion implementation is going to be similar to a Set add. As we need to check whether this element actually exists in DB or not. So if its marked extra-lazy we need to do existence check in DB without loaidng the collection. If its not marked then we need to load the collection and then do the operation on actual collection. Similar to add this can also have lazy behavior and it can be delayed till we load the collection by queuing this operation. Also it needs to mark the collection dirty after this opertaion.

                 f.)  clear operation on collection

                        This opertaion implementation is very simple. If Collection has not been initialized yet.(It needs additional check whether its an Inverse Collection and whether its Orphan Delete or not). It will queue the operation. 

                         Otherwise it will execute the operation. Here hibernate does on smart check of isEmpty as if collection isEmpty it doesn need to clear. As without doing this check if it does clear then it would have needed to mark the collection dirty which would have been wrong. As clearing an Empty collection is not making Collection dirty.

                   What is “Dirty” ?

                   I referred to marking Collection dirty a lot in all operations. What affects does this have ? dirty Field will be used by Flush operations on Session, flush of the Entity Holding the Collection. And this flag is the one which is going to trigger sync of Collection state with the DB.

So we discussed two things one is Lazy Loading of Collection and other is Delayed Operations.

There are lot of details which i am going to discuss for Collection treatment in Hibernate. Till now i discussed Lazy Loading. This is going to be a series of blog Entries on Hibernate Collections. Next Articles in the series ares going to be:

1.  Fetching Collections from DB

2. Sync of Collection State with DB

3. Collections and Caching

4. Treatment of Cardinality in Collection

5. Different kind of Collections

6 Responses to “Hibernate Collections”

  1. Dusan says:

    Hi, why LinkedList, I mean even ordinary ArrayList is able to preserve order. Is there any special requirenment from the hibernate side to use LinkedList?

  2. michael says:

    LinkedList is not only for preserving order. You can easily add and remove element in LinkedList.

    What happen when you are adding or removing in ArrayList?

    For adding, If you are adding to the end of the list, ArrayList will check if the capacity need to expand to hold the new entry. If you are adding it in anywhere in the list using index, you are doing an array copy. Both can be very expensive for a large collection.

    For remove, you are always doing an arraycopy in ArrayList.

  3. Roshan Shrestha says:

    I think any List will preserve order. Using SortedSet and SortedMap, user will need to implement “Comparator” interface to determine the sorted order, and may not preserve insertion order.

    Regardless, a special “index” column needs to be defined in the database table to let Hibernate know of the insertion order.

  4. webscale says:

    Yes. Sorry for the confusion i created. Any List will preserve order not necessarily LinkedList.

    Other then implementing Comparator. we can use order-by=”FILENAME asc” to get order.

    Yes we need an “index” column as there is not other magic way to find out the order. I will be writing next article on fetching of collections. It will be great to have a reference model to do all analysis on. So i welcome suggestions for the model i can build all future Hibernate Collection articles. Thanks for your comment guys.

  5. Dusan says:

    Ahhhh, thanks.

  6. ShyamKrishna says:

    Needed more information regarding ‘persister’ attribute in Set. Information regarding lazy was good.

Leave a Reply

preload preload preload