Spring + Hibernate + Hibernate Search

Version 1

    Very often the question arises how to use/configure Hibernate/JPA and Hibernate Search within a web application using spring.

    The following example configuration works for me with:

    • Spring 2.0.3
    • Hibernate 3.2.5.ga
    • Hibernate Search 3.0.0GA

    To configure the domain model I used:

    • Hibernate Annotations 3.3.0.ga

     

    This is what you need:

    persistence.xml - This configures JPA, 2nd level cache, Hibernate Search. It has to be placed in the META-INF directory of jar file. if you are using ehcache as a second level cache you also should create and configure ehcache.xml

     

    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
        version="1.0">
        <persistence-unit name="YourPersistenceUnitName">
            <properties>
                <!-- 2nd level cache  -->
                <property name="hibernate.cache.provider_class"
                    value="net.sf.ehcache.hibernate.SingletonEhCacheProvider" />
                <property name="hibernate.cache.provider_configuration" value="/ehcache.xml" />
                <property name="hibernate.cache.use_second_level_cache"
                    value="true" />
                <property name="hibernate.generate_statistics" value="true" />
                <property name="hibernate.cache.use_structured_entries"
                    value="true" />
    
                <property name="hibernate.hbm2ddl.auto" value="${hbm2ddl}" />
                <property name="hibernate.show_sql" value="false" />
                <property name="hibernate.format_sql" value="false" />
                <property name="hibernate.jdbc.batch_size" value="100" />
    
                <!--  HSearch settings -->
                <property name="hibernate.search.default.indexBase"
                    value="${hibernateIndexDir}" />
                <property name="hibernate.search.default.directory_provider"
                    value="${hibernateDirectoryProvider}" />
            </properties>
        </persistence-unit>
    </persistence>
    

     

    jpaContact.xml - Spring configuration for entity manager. The MBeanExporter is optional and only works if you include the spring-jmx module. It is not needed, but can be helpful when debugging/profiling your application.

     

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:util="http://www.springframework.org/schema/util"
        xmlns:jndi="http://www.springframework.org/schema/jndi"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd
    http://www.springframework.org/schema/jndi http://www.springframework.org/schema/jndi/spring-jndi-2.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
    
        <!-- 
            Process @PersistenceContext to inject entity manager factory
            
            http://static.springframework.org/spring/docs/2.1.x/reference/orm.html#orm-jpa-straight
            http://static.springframework.org/spring/docs/2.1.x/api/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html
            
            Note: this post processor is implicitly supplied by context:annotation-config or context:component-scan, however,
            we explicitly choose not to use those mechanisms as they encourge dependency lookup (versus the more flexible dependency injection)        
        -->
        <bean
            class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
    
        <!-- 
            Create the JPA EntityManagerFactory
            
            http://static.springframework.org/spring/docs/2.1.x/reference/orm.html#orm-jpa-setup-lcemfb
            http://static.springframework.org/spring/docs/2.1.x/api/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.html
        -->
        <bean id="entityManagerFactory"
            class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            <property name="loadTimeWeaver">
                <bean
                    class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
            </property>
            <property name="dataSource" ref="dataSource" />
            <property name="jpaVendorAdapter">
                <bean
                    class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                    <property name="database" value="${database}" />
                    <property name="showSql" value="${show_sql}" />
                </bean>
            </property>
        </bean>
    
        <bean id="dataSource"
            class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="${db.driver}" />
            <property name="jdbcUrl" value="${db.url}" />
            <property name="user" value="${db.username}" />
            <property name="password" value="${db.password}" />
            <property name="initialPoolSize" value="5" />
            <property name="minPoolSize" value="5" />
            <property name="maxPoolSize" value="50" />
        </bean>
    
        <!--
            Create a transaction manager for JPA operations that exposes JPA transactions to the underlying
            JDBC connection.
            
            http://static.springframework.org/spring/docs/2.1.x/reference/orm.html#orm-jpa-tx 
            http://static.springframework.org/spring/docs/2.1.x/api/org/springframework/orm/jpa/JpaTransactionManager.html
        -->
        <bean id="transactionManager"
            class="org.springframework.orm.jpa.JpaTransactionManager">
            <property name="entityManagerFactory"
                ref="entityManagerFactory" />
        </bean>
    
        <bean class="org.springframework.jmx.export.MBeanExporter">
            <property name="autodetect" value="false" />
            <property name="assembler">
                <bean id="jmxAssembler"
                    class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
                    <property name="attributeSource">
                        <bean
                            class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" />
                    </property>
                </bean>
            </property>
            <property name="beans">
                <map>
                    <entry key="org.hibernate:name=statistics">
                        <bean class="org.hibernate.jmx.StatisticsService">
                            <property name="statisticsEnabled" value="true" />
                            <property name="sessionFactory">
                                <util:property-path
                                    path="entityManagerFactory.sessionFactory" />
                            </property>
                        </bean>
                    </entry>
                </map>
            </property>
        </bean>
    
        <!-- 
            process @Transactional to create transaction proxies 
            
            http://static.springframework.org/spring/docs/2.1.x/reference/transaction.html#transaction-declarative-annotations
        -->
        <tx:annotation-driven transaction-manager="transactionManager" />
    </beans>

     

    And last but not least you probably want to add this to your web.xml:

        <filter>
            <filter-name>hibernateFilter</filter-name>
            <filter-class>
                org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
            </filter-class>
        </filter>