Chapter 17. Hibernate

17.1. Introduction

The Hibernate Gps Device provides support for database indexing through the use of Hibernate ORM mappings. If your application uses Hibernate, it couldn't be easier to integrate Compass into your application (Sometimes with no code attached - see the petclinic sample).

Hibernate Gps Device utilizes Compass::Core OSEM feature (Object to Search Engine Mappings) and Hibernate ORM feature (Object to Relational Mappings) to provide simple database indexing. As well as Hibernate 3 new event based system to provide real time mirroring of data changes done through Hibernate. The path data travels through the system is: Database -- Hibernate -- Objects -- Compass::Gps -- Compass::Core (Search Engine).

Hibernate Gps Device extends Compass Gps AbstractParallelGpsDevice and supports parallel index operations. It is discussed in more detail here: Section 14.5, “Parallel Device”.

17.2. Configuration

When configuring the Hibernate device, one must instantiate HibernateGpsDevice. After instantiating the device, it must be initialized with a Hibernate SessionFactory.

Here is a code sample of how to configure the hibernate device:

Compass compass = ... // set compass instance
SingleCompassGps gps = new SingleCompassGps(compass);
CompassGpsDevice hibernateDevice = new HibernateGpsDevice("hibernate", sessionFactory);
.... // configure other devices

In order to register event listener with Hibernate SessionFactory, the actual instance of the session factory need to be obtained. The Hibernate device allows for a pluggable NativeHibernateExtractor implementation responsible for extracting the actual instance. Compass comes with a default implementation when working within a Spring environment called: SpringNativeHibernateExtractor.

17.2.1. Deprecated Hibernate Devices

For backward compatibility, Compass supports previous Hibernate2GpsDevice and Hibenrate3GpsDevice. The classes have moved to a different package, and are usable with a simple change to the package name. The new package for the deprecated devices is: org.compass.gps.device.hibernate.dep. Configuration

When configuring the Hibernate device, one must instantiate either Hibernate2GpsDevice (for Hibernate 2 version) or Hibernate3GpsDevice (for Hibernate 3 version). After instantiating the device, it must be initialized by either a Hibernate Configuration or a Hibernate SessionFactory. When configuring the device with Hibernate Configuration, a new SessionFactory is created when the device is started.

It is more preferable to configure the device with the SessionFactory that the actual application will use, especially since data mirroring will only work when both the device and the application will use the same SessionFactory.

Here is a code sample of how to configure the hibernate device:

Compass compass = ... // set compass instance
SingleCompassGps gps = new SingleCompassGps(compass);
CompassGpsDevice hibernateDevice =
// If Hibernate 2
     new Hibernate2GpsDevice("hibernate", sessionFactory);
// If Hibernate 3
     new Hibernate3GpsDevice("hibernate", sessionFactory);
.... // configure other devices

17.3. Index Operation

Hibernate Gps device provides the ability to index a database. Compass will index objects (or their matching database tables in the Hibernate mappings) specified in both the Hibernate mappings and Compass::Core mappings (OSEM) files.

The indexing process is pluggable and Compass comes with two implementations. The first, PaginationHibernateIndexEntitiesIndexer, uses setFirstResult and setMaxResults in order to perform pagination. The second one, ScrollableHibernateIndexEntitiesIndexer, uses Hibernate scrollable resultset in order to index the data. The default indexer used is the scrollable indexer.

During the indexing process Compass will execute a default query which will fetch all the relevant data from the database using Hibernate. The query itself can be controlled both by setting a static sql query and providing a query provider. This setting applies per entity. Note, when using the scrollable indexer, it is preferable to use a custom query provider that will return specific Hibernate Criteria instead of using static sql query.

17.4. Real Time Data Mirroring

The Hibernate Gps Device, with Hibernate 3 new event system, provides support for real time data mirroring. Data changes via Hibernate are reflected in the Compass index. There is no need to configure anything in order to enable the feature, the device takes care for it all.

An important point when configuring the hibernate device is that both the application and the hibernate device must use the same SessionFactory. Which means that the device must be configured with a SessionFactory and not a Configuration.

Note on Hibernate 2 and Interceptors. When using generated ids with Hibernate 2, the id in the interceptor is null, which means that when creating new objects and persisting them to the database, the device has no way to index the object. If Hibernate 2 is a must, one possible solution is to use aspects.

If using Hibernate 3 and the Spring Framework, please see the SpringHibernate3GpsDevice

17.5. HibernateSyncTransaction

Compass integrates with Hibernate transaction synchronization services. This means that whichever Hibernate transaction management is used (Jta, JDBC, ...) you are using, the HibernateSyncTransaction will synchronize with the transaction upon transaction completion. The Hibernate transaction support uses Hibernate context session in order to obtain the current session and the current transaction. The application using this feature must also use Hibernate context session (which is the preferred Hibernate usage model starting from Hibernate 3.2).

If you are using the HibernateSyncTransaction, a Hibernate based transaction must already be started in order for HibernateSyncTransaction to join. If no transaction is started, Compass can start one (and will commit it eventually). Note, if you are using other transaction management abstraction (such as Spring), it is preferable to use it instead of this transaction factory.

In order to configure Compass to work with the HiberanteSyncTransaction, you must set the compass.transaction.factory to org.compass.gps.device.hiberante.transaction.HibernateSyncTransactionFactory. Additional initialization should be performed by calling HibernateSyncTransactionFactory.setSessionFactory with Hibernate SessionFactory instance before the Compass is created.

17.6. Hibernate Transaction Interceptor

When working with Hibernate transactions (and not utilizing Hibernate context session) and Compass local transactions, an Compass implementation of Hibernate Interceptor can be used to synchronize with a Hibernate session. CompassTransactionInterceptor can be used to inject an instance of itself into Hibernate SessionFactory. Please refer to its javadoc for more information.