Thursday, January 12, 2012

Migrate to Hibernate 4 and Spring 3.1 - SessionFactory

As most of you probably have to do these days or in the near future we have to migrate our project to the newest Versions ob Hibernate and Spring. Actually the Version numbers are
  • Hibernate 4.0.0.Final
  • Hibernate Search 4.0.0.Final
  • Spring 3.1.0.RELEASE
If you want to perform a complete migration you'll need to change also to Spring 3.1. because in that version they added support for hibernate 4. For example they added the package
org.springframework.orm.hibernate4
which is needed for example to create the org.springframework.orm.hibernate4.LocalSessionFactoryBean which defines all the annotated classes and the hibernate properties needed to create the session

<!-- Hibernate SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" p:dataSource-ref="dataSource">
<property name="annotatedClasses">
<list>
<value>org.something.myClass</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=${hibernate.dialect}
hibernate.connection.driver_class=${hibernate.connection.driver_class}
hibernate.connection.url=${hibernate.connection.url}
hibernate.connection.username=${hibernate.connection.username}
hibernate.connection.password=${hibernate.connection.password}
hibernate.default_schema=${hibernate.default_schema}
hibernate.hbm2ddl.auto=${hibernate.hbm2ddl.auto}
hibernate.jdbc.batch_size=${hibernate.jdbc.batch_size}
hibernate.c3p0.max_size=${hibernate.c3p0.max_size}
hibernate.c3p0.min_size=${hibernate.c3p0.min_size}
hibernate.c3p0.timeout=${hibernate.c3p0.timeout}
hibernate.c3p0.max_statements=${hibernate.c3p0.max_statements}
hibernate.c3p0.idle_test_period=${hibernate.c3p0.idle_test_period}
hibernate.c3p0.acquire_increment=${hibernate.c3p0.acquire_increment}
hibernate.c3p0.validate=${hibernate.c3p0.validate}
hibernate.cache.region.factory_class=${hibernate.cache.region.factory_class}
hibernate.connection.provider_class=${hibernate.connection.provider_class}
hibernate.show_sql=${hibernate.show_sql}
hibernate.generate_statistics=${hibernate.generate_statistics}
hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=true
</value>
</property>
</bean>
As you can see there is no definition of  eventlisteners whatsoever. Before version 3.6 of hibernate-search the changelisteners where defined here, which is now obsolete.

<!-- Obsolete in 3.6: FullTextIndexEventListener default constructor is obsolete. Remove all explicitevent listener configuration. As of Hibernate Core 3.6 Hibernate Search will be automatically enabled if it is detectedon the classpath.
<property name="eventListeners">  
<map>
<entry key="post-update">
<bean class="org.hibernate.search.event.FullTextIndexEventListener" />
</entry>
<entry key="post-insert">
<bean class="org.hibernate.search.event.FullTextIndexEventListener" />
</entry>
<entry key="post-delete">
<bean class="org.hibernate.search.event.FullTextIndexEventListener" />
</entry>
</map>
</property>-->
Another interesting change is that the class definition not just changed from hibernate3 to hibernate4 but in our case from org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean into org.springframework.orm.hibernate4.LocalSessionFactoryBean.
This leads to the lost of the possibility of defining a lobHandler which according to the JavaDoc of the LobHandler interface is still a good practice. I asked about this at stackoverflow, but I didn't got an answer yet, so I asked it today on the spring forum.


Furthermore you notice that now the complete connection properties including the c3p0 (cache) definition is defined in this bean. This makes it much simpler because there is no additional "datastore" bean needs to be there.
However there is still a "datastore" bean which needs to be defined otherwise you'll get a NullPointerException. (UPDATE: This will apparently be fixed in Spring 3.1.1)


Another important thing that needs to be defined in this bean is the hibernate-search. It's properties changed slightly in version 4.0 and the most important ones are shown below.
hibernate.search.lucene_version=${hibernate.search.lucene_version}
hibernate.search.analyzer=${hibernate.search.analyzer}
hibernate.search.default.directory_provider=${hibernate.search.default.directory_provider}
hibernate.search.default.filesystem_access_type=${hibernate.search.default.filesystem_access_type}
hibernate.search.default.locking_strategy=${hibernate.search.default.locking_strategy}
hibernate.search.default.indexBase=${hibernate.search.default.indexBase}
hibernate.search.default.indexmanager=${hibernate.search.default.indexmanager}
hibernate.search.default.refresh=${hibernate.search.default.refresh}
hibernate.search.default.reader.strategy=${hibernate.search.default.reader.strategy}
The real values of the properties depend highly on your environment, however if you need my values just drop me a comment and I'll add them.

UPDATE:
Unfortunately there is still an Error in hibernate 4.0.0.Final regarding the progress monitor when re-indexing the whole database. It seems that this error was found in CR1then fixed in CR2 and reappeared in the final version

No comments: