Upgrading to Hibernate Search 3.2.0 (w/ Seam)
31 May 2010A couple weeks back I set out to upgrade the version of Hibernate Search that one of our applications was using.
The boys at JBoss had recently released Hibernate Search 3.2.0 and it looked pretty sweet. The possibility of performance improvements around indexing was enough to make me upgrade.
Unfortunately, like most software frameworks, Hibernate Search introduced/forced some new dependencies on us. We had previously been using Seam 2.2.0 and Hibernate 3.3.0 (both JPA1), neither of which were compatible with Hibernate Search 3.2.0.
We’re using Maven, so I’ll quickly outline the dependency changes I had to make (*all dependences are available via the [JBoss Nexus Repository*]2):
javax.persistence
persistence-api
<!– bit of a hack to make sure we aren’t transitively pulling in the persistence api (should be referencing hibernate-jpa-2.0-api now) –->
explicitly-fail
javax.persistence:persistence-api is the JPA1 API and is no longer relevant and should never be included as a dependency. The explicitly-fail version will trigger a build failure if it ever manages to sneak in.
org.hibernate.javax.persistence
hibernate-jpa-2.0-api
1.0.0.Final
org.hibernate.javax.persistence:hibernate-jpa-2.0-api is the new JPA2 API published by Hibernate.
All previous hibernate dependencies had to be upgraded to 3.5.2.Final, and Hibernate Search bumped up to** 3.2.0.Final**.
If you’re using Seam, you’ll also need to upgrade it to 2.2.1.CR1. Note that this is not yet a final release but is necessary in order to support JPA2.
Unfortunately, Seam 2.2.1.CR1 lacks a complete Hibernate Search integration. I could no longer able properly inject a FullTextEntityManager (via @In).
Instead I was forced to obtain a FullTextSession programmatically:
private FullTextSession getFullTextSession()
{
Session session = (Session) entityManager.getDelegate();
return Search.getFullTextSession (session.getSessionFactory().getCurrentSession());
}
Seam also enhanced it’s EntityManager so that it now returns a JDK proxy when getDelegate() is called.
That would be fine and dandy, but unfortunately the proxy does not implement org.hibernate.classic.Session, as required by the FullTextSession in Hibernate Search.
Session.getSessionFactory().getCurrentSession() will return an org.hibernate.classic.Session and does allow you to move forward.
A bit annoying and hopefully something that will get corrected in the near future. I’m hoping that either Hibernate Search will be upgraded to not require a classic session, or Seam will provide an EntityManager delegate implementing the classic session interface. Better yet, Seam should just provide a fully supported integration with Hibernate Search 3.2.0.
Honestly, that was about it as far as the upgrade went. We were able to index using either the new MassIndexer API or the old suggested best practice from Hibernate Search 3.1.
It’s interesting to note that on my test system, the MassIndexer API was slower than the previous indexing code. The documentation does cover many different tuning possibilities so it’s entirely possible the situation could be improved.
Also, the MassIndexer API runs in a series of transactions and unless your timeout is set sufficiently high (ie. higher than the default JBoss 5 minutes), you will see transaction timeouts.
I didn’t attempt to work around this and opt’d to stick with existing indexing code that already runs in a separate Seam @Asynchronous method (thus avoiding timeouts).
Somewhat less than ideal, but if you’re keen on running Hibernate Search 3.2.0 w/ Seam in JBoss 4.2.3, it *is possible ***and not too much work.