Spring 3 and JPA with Hibernate

Table of Contents

1. Overview

This is tutorial shows how to set up Spring with JPA, using Hibernate as a persistence provider.

For a step by step introduction about setting up the Spring context using Java based configuration and the basic Maven pom for the project, see this article.

2. The JPA Spring Configuration with Java

To use JPA in a Spring project, the EntityManager needs to be set up.

This is the main part of the configuration – and it is done via a Spring factory bean – either the simpler LocalEntityManagerFactoryBean or the more flexible LocalContainerEntityManagerFactoryBean. The latter option is used here, so that additional properties can be configured on it:

@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig{

   @Bean
   public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
      LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
      em.setDataSource(dataSource());
      em.setPackagesToScan(new String[] { "org.baeldung.persistence.model" });

      JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
      em.setJpaVendorAdapter(vendorAdapter);
      em.setJpaProperties(additionalProperties());

      return em;
   }

   @Bean
   public DataSource dataSource(){
      DriverManagerDataSource dataSource = new DriverManagerDataSource();
      dataSource.setDriverClassName("com.mysql.jdbc.Driver");
      dataSource.setUrl("jdbc:mysql://localhost:3306/spring_jpa");
      dataSource.setUsername( "tutorialuser" );
      dataSource.setPassword( "tutorialmy5ql" );
      return dataSource;
   }

   @Bean
   public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
      JpaTransactionManager transactionManager = new JpaTransactionManager();
      transactionManager.setEntityManagerFactory(emf);

      return transactionManager;
   }

   @Bean
   public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
      return new PersistenceExceptionTranslationPostProcessor();
   }

   Properties additionalProperties() {
      Properties properties = new Properties();
      properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
      properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
      return properties;
   }
}

Also, note that, before Spring 3.2, cglib had to be on the classpath for Java @Configuration classes to work; to better understand the need for cglib as a dependency, see this discussion about the cglib artifact in Spring.

3. The JPA Spring Configuration with XML

The same Spring Configuration with XML:

<?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:tx="http://www.springframework.org/schema/tx"
   xsi:schemaLocation="
      http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
      http://www.springframework.org/schema/tx 
      http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

   <bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
      <property name="dataSource" ref="dataSource" />
      <property name="packagesToScan" value="org.baeldung.persistence.model" />
      <property name="jpaVendorAdapter">
         <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
      </property>
      <property name="jpaProperties">
         <props>
            <prop key="hibernate.hbm2ddl.auto">create-drop</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
         </props>
      </property>
   </bean>

   <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName" value="com.mysql.jdbc.Driver" />
      <property name="url" value="jdbc:mysql://localhost:3306/spring_jpa" />
      <property name="username" value="tutorialuser" />
      <property name="password" value="tutorialmy5ql" />
   </bean>

   <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
      <property name="entityManagerFactory" ref="myEmf" />
   </bean>
   <tx:annotation-driven />

   <bean id="persistenceExceptionTranslationPostProcessor" 
      class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

</beans>

There is a relatively small difference between the way Spring is configured in XML and the new Java based configuration – in XML, a reference to another bean can point to either the bean or a bean factory for that bean. In Java however, since the types are different, the compiler doesn’t allow it, and so the EntityManagerFactory is first retrieved from it’s bean factory and then passed to the transaction manager:

txManager.setEntityManagerFactory( this.entityManagerFactoryBean().getObject() );

4. Going full XML-less

Usually JPA defines a persistence unit through the META-INF/persistence.xml file. Starting with Spring 3.1, the persistence.xml is no longer necessary – the LocalContainerEntityManagerFactoryBean now supports a ‘packagesToScan’ property where the packages to scan for @Entity classes can be specified.

This file was the last piece of XML to be removed – now, JPA can be fully set up with no XML.

4.1. The JPA Properties

JPA properties would usually be specified in the persistence.xml file; alternatively, the properties can be specified directly to the entity manager factory bean:

factoryBean.setJpaProperties( this.additionalProperties() );

As a side-note, if Hibernate would be the persistence provider, then this would be the way to specify Hibernate specific properties.

5. The Maven configuration

In addition to Spring Core and persistence dependencies – show in detail in the Spring with Maven tutorial – we also need to define JPA and Hibernate in the project, as well as a MySQL connector:

<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-entitymanager</artifactId>
   <version>4.3.5.Final</version>
   <scope>runtime</scope>
</dependency>

<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>5.1.30</version>
   <scope>runtime</scope>
</dependency>

Note that the MySQL dependency is included as a reference – a driver is needed to configure the datasource, but any Hibernate supported database will do.

6. Conclusion

This tutorial illustrated how to configure JPA with Hibernate in Spring using both XML and Java configuration.

We also discussed how to get rid of the last piece of XML usually associated with JPA – the persistence.xml. The final result is a lightweight, clean DAO implementation, with almost no compile-time reliance on Spring.

The implementation of this Spring JPA Tutorial can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.

I usually post about Persistence on Google+ - you can follow me there:

Free eBook - REST Services with Spring
Join more than 2,200 engineers!

, , ,

  • Milos Nikic

    I do not want to sound offensive but I sigh when i see that people still use things such as AbstractJpaDao, but to each his own.

    Btw There is a reason why merge method on entity manager doesn’t have void as a return type.Don’t change that with you AbstractJpaDao methods.

  • Eberhard Wolff

    Thanks for the article! You should consider Spring Data JPA – it has quite a few nice features around generic DAOs: http://www.springsource.org/spring-data/jpa

  • Constantine

    Spring Data JPA (formerly known as Hades) is based on the same principle and takes the approach much further. With it being available for so now – as part of Spring – I’m not sure I see the relevance of this otherwise formidable post.

    • Eugen

      Thank you for the suggestion. As it happens, the latest article (just published today) is indeed on Spring Data.

  • ctrlspace

    How would I use this to configure an active record style of pojo instead of using daos? I’m having issues with:
    Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)

    • ctrlspace

      got it to work by adding:
      @EnableSpringConfigured
      to the ApplicationConfig but I’m not sure why that worked.

  • Tsingh007

    should FooDAO extends AbstractHibernateDAO not be like extents JPADAO?

    • Eugen

      Yes it should. Thanks for the feedback.

  • Tsingh007

    Need your thoughts:

    I am getting exception – no persistent classes found for query class:

    i have added and under the domain folder i have got the Entity class.

    • Tsingh007

      sorry the tag got removed from above post < property name="packagesToScan" value="com.something.domain

      • Tsingh007

        tried adding
        and also added

        but no still when i run
        public List findAll(){
        List data=dao.findAll();
        return data;

        i get 0 results even though there are two rown in the table

        • Tsingh007

          bean class=”org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor”

          property name=”dataSource” ref=”dataSource” />
          property name=”persistenceProvider” >
          bean class=”org.hibernate.ejb.HibernatePersistence” ></bean
          </property

  • Gauthier Peel

    I don’t see any @Transactional on your classes. So how could the works ?

    • Eugen

      The code samples are not meant to be the full implementation, but only focus on the relevant details presented in the article. The @Transactional annotation was removed to simplify things, but for a full implementation please check out the gihub project (link at the end of the article). Also, there is another article in the series that deals specifically with @Transactional.
      Hope this helps.
      Eugen.

      • Gauthier Peel

        thanks, i will check out the whole project.
        I noticed you uused :
        public FooDAO(){ setClazz(Foo.class ); }

        I used the follwing trick (not it is always valid though) in the abstract class :

        private Class clazz;

        @SuppressWarnings(“unchecked”)
        public AbstractJpaDAO() {
        this.clazz= ((Class) ((ParameterizedType) getClass().getGenericSuperclass())
        .getActualTypeArguments()[0]);
        }

        so the subclass does not need to give a value to clazz …

  • Kpkeerthi

    Where is the method getById() defined?

  • Pingback: Bean life cycle in spring « Zeeshan Akhter

  • Carlos Dañel Ferreyra
  • robbiepl

    use spring-data-jpa or mybatis :)

  • mwmahlberg

    Thanks a million for the xml configuration – for me as beeing new to spring I realy had a hard time to figure that one out.

  • kriolcv

    nice tutorial

  • s

    this is really good

  • Kim

    I tried your tutorial but alas … My entitymanager is always null. Why? Thank you in advance.

    Excuse my English

    • baeldung

      There are many reasons this may happen – did you try to start from the example project the article is pointing to (at the end)?
      Thanks. Eugen.

  • eugene

    Hi.. can’t seem to make it work. I deleted my persistence.xml and have my config in JPA context file.
    When I have persistence.xml, with empty persistence unit. i get an error that class is not mapped. when i deleted persistence.xml i have this error: no persistence.xml.

    Do you know how to solve this?

    • baeldung

      Did you try to clone the example project? That should give a good base to build your JPA configuration upon. If you find any problem starting from this point – please go ahead and create an issue on github and I’ll look into it.
      Thanks. Eugen.

      • eugene

        I tried importing your spring-jpa project. and found no major differences on the setup/configuration. What I noticed is that, the JPA Facets is not clicked in your project. Apparently, this solves my issue when I removed it. Thanks a lot.

        ps
        regarding the config above, may i know what’s advisable? using the java config or the xml – jpaConfig? I’m also wondering where are your dispatcher servlet and view resolvers configured. (sorry, just started learning spring/jpa-hibernate) TIA.

        • baeldung

          Glad the sample project helped. As for what to use – java or XML config, these are very much equivalent, so it’s a matter of preference. I a new project, I personally prefer to use java config. The Dispatcher, controllers and generally the web configuration lives in a different config file – this one is simply persistence, with the goal to keep things as separate and decoupled as possible.

  • Rupanjan Baidya

    Baeldung,

    Do you have any implementation of mybatis with JPA + Spring Data Solr?

    Thank you in advance.

    • baeldung

      I do not have an already implemented example for this stack yet. I think the MyBatis configuration for JPA should be very similar to the Hibernate implementation, and for Spring Data Solr, I recomend this excelent tutorial.
      Hope it helps.
      Eugen.

  • Giuseppe Sergio

    Could you Explain how to make work the project XML-Less in tomcat7?

    how i should declare my web.xml? and the Struts.xml?
    Thank you in advance.

  • Mike

    Why aren’t you using Spring Injection to inject your beans in the configuration as well?

    Instead of this:

    @Bean
    public PlatformTransactionManager transactionManager() {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());
    return transactionManager;
    }

    You can do this (and get rid of the getObject() call at the same time):

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(emf);
    return transactionManager;
    }

    • baeldung

      I was initially trying to keep the Java configuration as close to the original XML configuration as possible, but you’re right – this is cleaner – thanks for pointing it out.
      Cheers,
      Eugen.

  • Ashish Saraf

    Hi,
    Very nice tutorial to illustrate java class configuration for spring-jpa application. When persistence.xml is used, one can define multiple persistence-unit, for multiple database connections. I would appreciate if you could help with an illustration to define such a scenario using java class configuration.
    Thanks and regards,
    Ashish Saraf

    • http://www.baeldung.com/ Eugen Paraschiv

      Hi Ashis – I will cover this in a subsequent article – since this is more of an introduction than advanced usage. If you need it quickly – I don’t think you’ll have any problem defining multiple datasources and working with them separately. The only thing to keep in mind is that – if you only have one data source and one transaction manager – you’re landing on the “Convention” side of “Conversion over Configuration” – if you have more than one, with different names, you’ll be more on the “Configuration” side.
      Cheers.
      Eugen.

      • Ashish Saraf

        Hi Eugen,
        Thanks for the reply. Would you suggest some reference documentation to this please.
        I will really appreciate.
        Thanks and regards,
        Ashish Saraf

  • rswrc

    Right now i use JBOSS AS 6.1 and have a persistence.xml nad a myProject-ds.xml where the database url , username, password and driver class name is stored. When i remove persistence.xml should i also remove this *-ds.xml? Anf if yes how do i make it to read on my dev machine my dev database and on the production machince the production db? Right now i can work like this.

    • http://www.baeldung.com/ Eugen Paraschiv

      Not sure about the specifics of working with JBoss 6 (I haven’t worked with it for a while now) – but about the configuration – shouldn’t be hard. Keep in mind that the example above is hardcoded for readability but what you want here is not to hardcode any of these values. Instead you simply load them up from properties – checkout the github project as that uses properties, not hardcoded values. Then – you need a mechanism to load a property based on the environment – you can do that in more than one way – here is a simple one I wrote about. That should sort out both problems. Hope this helps.
      Cheers.
      Eugen.

      • rswrc

        Thx. Your articles are very well written.

        • http://www.baeldung.com/ Eugen Paraschiv

          No worries, glad you’re finding the articles useful.
          Cheers.

  • Thiruppathy.R

    Thank you for the useful details!

  • http://www.jooq.org Lukas Eder

    I don’t think it’s a good idea to create an anonymous inner class that extends Properties. As any inner class, this will keep a reference to its outer class – PersistenceJPAConfig, in this case. This instance (and the outer class reference) are then passed to the LocalContainerEntityManagerFactoryBean (what a class name ;-) ) whose lifecycle might be quite different now or in the future, just to save 1-2 lines of code.

    Creating such anonymous classes is almost always a bad idea, see Rule #3 of our article here.

    • http://www.baeldung.com/ Eugen Paraschiv

      Hey Lukas,
      Thanks for the suggestion – you’re absolutely right – no point in holding on to that reference. I updated the tutorial code and the article to simply initialize a Properties object.

      Cheers,

      Eugen.

Powered by WordPress. Designed by Woo Themes