Documentation‎ > ‎

Hibernate

Overview

With the upcoming Hibernate extension (presumably released with GlazedLists 1.8.0) you will be able to persist a BasicEventList with Hibernate directly. The following description assumes a basic knowledge of Hibernate and how to persist and map a normal java collection. These are the required steps to persist an EventList with Hibernate:


List property declaration in entity class

Ensure you have an appropriate property declaration for your EventList in your mapped entity class.

For example, consider a simple class User, that has a list of nicknames you want to persist as an EventList.

The class would look like:

public class User {
private EventList<String> nickNames = new BasicEventList<String>();
...
public EventList<String> getNickNames() {
return nichNames;
}

public void setNickNames(EventList<String> nickNames) {
this.nickNames = nickNames;
}
...
}

Notice the declaration of the field nickNames of type EventList. Hibernate requires you to use and program against the collection interfaces instead of concrete implementation classes. This applies to GlazedLists as well. So please use the interface EventList as the field type.

To access the list, Hibernate uses the JavaBeans conventions for properties as default. So you should provide appropriate getter- and setter-methods for your list property as demonstrated above. Alternatively, you could configure Hibernate to use direct field access. In this case, the getter/setter methods are not required.


Hibernate mapping for EventLists

Basically, an EventList is mapped like a normal List with one exception:

...
<class name="User" table="`USERS`">
...
<list name="nickNames" table="USER_NICKNAMES" collection-type="ca.odell.glazedlists.hibernate.EventListType">
<key column="USER_ID"/>
<list-index column="DISPLAY_ORDER"/>
<element column="NAME" type="string" length="50"/>
</list>
</class>
...

You have to specify the custom Hibernate type EventListType as the collection type. With this information, Hibernate knows how to persist and load your EventList as a BasicEventList.

EventList usage

You can use the mapped EventList like any other BasicEventList in your code. Just keep in mind, although the list behaves like a BasicEventList, its concrete runtime type will be ca.odell.glazedlists.hibernate.PersistentEventList.


Advanced usage

EventLists loaded with Hibernate will always end up having their own lock and publisher. Most of the time this is no problem, because these lists will be the root of list transformations usually. But sometimes, for example when using CollectionLists or CompositeLists, this could be an issue. Therefore you can customize the EventList creation by

  • using list categories provided by GlazedLists to group EventLists together which should share a common ReadWriteLock and ListEventPublisher.
  • providing a custom EventListFactory to EventListType

Using list categories

A list category is a User-defined String that will be associated with a dedicated ReadWriteLock and ListEventPublisher. By specifying a list category for an EventListType, all EventLists created by this type will use the same ReadWriteLock and ListEventPublisher associated with the list category. You can even specify which lock and publisher to use for a dedicated list category. Currently, you have to programmatically set the desired list category on your EventListType by subclassing:

/** Custom EventListType using a list category. */
public class MyEventListType extends EventListType {
/** Constructor which sets a list category. */
public MyEventListType() {
useListCategory("Account");
}
}

Or:

/** Custom EventListType using a list category with specified lock and publisher. */
public class MyEventListType2 extends EventListType {
/** Lock as constant. */
public static final ReadWriteLock LOCK = LockFactory.DEFAULT.createReadWriteLock();
/** Publisher as constant. */
public static final ListEventPublisher PUBLISHER = ListEventAssembler.createListEventPublisher();

/** Constructor which sets a list category. */
public MyEventListType() {
useListCategory("Order", LOCK, PUBLISHER);
}
}

With Hibernate >= 3.2.4, which includes a fix for Hibernate bug HHH-2336, you are able to configure the list category as a parameter of the collection type in the Hibernate mapping file, so you don't have to subclass EventListType. Here is an example:

...

<typedef name="MyEventListType" class="ca.odell.glazedlists.hibernate.EventListType">
<param name="EventList.category">Nicknames</param>
</typedef>

<class name="User" table="`USERS`">
...
<list name="nickNames" table="USER_NICKNAMES" collection-type="MyEventListType">
<key column="USER_ID"/>
<list-index column="DISPLAY_ORDER"/>
<element column="NAME" type="string" length="50"/>
</list>
</class>
...

Using a custom EventListFactory

If list categories don't fit your needs, you can provide your own factory for EventList creation. First implement this simple interface:

package ca.odell.glazedlists.hibernate;
...
public interface EventListFactory {

/**
* Creates a new EventList.
*/
EventList createEventList();

/**
* Create a new EventList with an initial capacity.
*/
EventList createEventList(int initalCapacity);
}

Then subclass EventListType to set the new ListFactory.

public class MyEventListType extends EventListType {
/** Constructor which sets a list category. */
public MyEventListType() {
setListFactory(new MyEventListFactory());
}
}

Instead of using EventListType in your Hibernate mapping files you would now use your custom MyEventListType.


Caveats

When using Hibernate 3.1.x you could run into Hibernate issue HHH-1586. This is not specific to GlazedLists but to all CustomCollectionTypes. As a workaround, don't enable DEBUG logging or upgrade to a newer Hibernate version.

Comments