Mock tests, Interview questions, Tutorials and Tech news
 
 
Home > Programming / tutorials > Integrating hibernate search with a Spring and JPA Application

Integrating hibernate search with a Spring and JPA Application

In this post we will talk about how to integrate hibernate Search into your existing Spring, JPA and Hibernate application and some of the challenges we faced.

We  have a web application using Hibernate (with JPA ) and Spring. This application relies on Spring for transaction, bean initialization / injection etc. EntityManager, transaction are configured in application.xml file. When integrating Hibernate search in such an application one might face problems. In this post I am sharing some problems I faced during integration and the solutions for same.

Entitymanager configuration in my application.xml

Spring configuration:
<bean id=”propertyConfigurer”>
<property name=”location” value=”classpath:myproperties.properties”/>
</bean>


<bean id=”dataSource” destroy-method=”close”>
<property name=”driverClass” value=”${db.driverClass}”/>
<property name=”jdbcUrl” value=”${db.url}”/>
<property name=”user” value=”${db.username}”/>
<property name=”password” value=”${db.password}”/>
<property name=”minPoolSize” value=”2″/>
<property name=”maxPoolSize” value=”8″/>
<property name=”breakAfterAcquireFailure” value=”false”/>
<property name=”acquireRetryAttempts” value=”3″/>
<!– property name=”idleConnectionTestPeriod” value=”300″ –>
<property name=”testConnectionOnCheckout” value=”true”/>
</bean>

<bean id=”entityManager”
p:dataSource-ref=”dataSource”>
<property name=”persistenceUnitName” value=”defaultManager” />
<property name=”jpaVendorAdapter”>
<bean>
<property name=”database” value=”${jpa.database}”/>
<property name=”showSql” value=”${jpa.showSql}”/>
</bean>
</property>
</bean>

<bean id=”transactionManager”
p:entityManagerFactory-ref=”entityManager”/>

In the base DAO, I have  entityManager  as class level variable, value to which will be injected by spring:

@PersistenceContext(unitName = “defaultManager”)
private EntityManager entityManager;
For Hibernate search we need FullTextEntityManager. This instance of FullTextEntityManager  will be created using entityManager as below:
fullTextEntityManager = Search.getFullTextEntityManager(entityManager);

To make fullTextEntityManager available for search in the DAO class , I creates a class level variable fullTextEntityManager and  initialized this in @postConstruct method (after entityManager injection) as below.
@PersistenceContext(unitName = “defaultManager”)
private EntityManager entityManager;

FullTextEntityManager fullTextEntityManager;

public abstractDAO(){
super();

@PostConstruct
public void setPersistenceUnit(){
super.setUnit(entityManager);
fullTextEntityManager = Search.getFullTextEntityManager(entityManager);

}

public FullTextEntityManager getFullTextEntityManager(){
return fullTextEntityManager;
}
But this approach gave me
org.hibernate.SessionException: Session is closed!
Exception whenever I tried to search.

My initial action was to look into index directory to see if they are being created. It looked perfectly ok there.

The problem was, search operation was not getting transaction while searching. The spring was not injecting transaction into a fullTextEntityManager created from entityManager.

For a try I introduced EXTENDED persistence context as below:
@PersistenceContext(unitName = “defaultManager”,type=PersistenceContextType.EXTENDED)
private EntityManager entityManager;

and search started working!! But this gave me other problems. Any changes to the entity bean got saved into DB without even committing!!!! I had to revert this change.

My second approach to solve this was to configure fullTextEntirtyManager as Spring bean (as entityManager was configured) so that it can get the transaction.
I couldn’t do it properly as I found no spring’s implementation for fullTextEntirtyManager bean configuration.

After a lot of tries and searching, just changing my DAO code solved this. Instead of making FullTextEntityManager a class level variable, I instatiated it from entityManager whenever I wanted to search. Something like below:

@PersistenceContext(unitName = “defaultManager”)
private EntityManager entityManager;

public abstractDAO(){
super();
}

@PostConstruct
public void setPersistenceUnit(){
super.setUnit(entityManager);

}

public FullTextEntityManager getFullTextEntityManager(){
FullTextEntityManager fullTextEntityManager;
fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
return fullTextEntityManager;
}
This solved my problem and the search is working perfectly now.

Going for an interview or want to test your hibernate skills , check out our hibernate interview questions

Be Sociable, Share!
  1. slack.br
    April 9th, 2012 at 07:37 | #1

    Hi,

    You hava a example that application working? please :)

  2. July 21st, 2010 at 07:16 | #2

    In the past I’ve just thrown in Springs OpenEntityManagerInViewFilter into the web.xml for my tomcat to get around these Session closed issues (obviously people need tighter scoped transactions sometimes but for RAD stuff this gets thing running)

    openSessionInViewFilter
    org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter

    openSessionInViewFilter
    /*

  1. No trackbacks yet.

Get Adobe Flash playerPlugin by wpburn.com wordpress themes