Spring 4 and JPA with Hibernate

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

 

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 entityManagerFactory() {
      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 downloaded as a working sample 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:

>> GET THE EBOOKS <<
Get the eBooks and Learn to Build a Simple App
×
Build a Simple but Working App with Spring

, , ,

  • Gauthier Peel

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

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

      The DAO is not @Transactional – the service layer is, and since this article focuses on DAO layer, that’s not included. Note that there is an article dealing specifically with transaction configuration: http://www.baeldung.com/2011/12/26/transaction-configuration-with-jpa-and-spring-3-1/

      • 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 …

  • Pingback: Bean life cycle in spring « Zeeshan Akhter()

  • 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.

  • Kim

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

    Excuse my English

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

      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?

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

      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.

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

          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.

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

      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.

  • 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.

  • raam

    Hey thanks for your great tutorial.
    How can we avoid PersistenceJPAConfig and PersistenceJPAConfigXml and just use applicationContext.xml. In production it does not make sense to have both class file and xml. I am looking for example where we can configure only with the applicationContext.xml. Can you give me some pointers how can I make it.

    Thanks in advance

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

      Hey Raam – the article illustrates 2 alternative configurations – one in Java and the other in XML. You only need to use one of them, not both. I personally prefer the Java approach, but feel free to use the XML one if you need to. Hope that clarifies thins. Cheers,
      Eugen.

  • Amara Bargougui

    Hi,
    thank you for this tutorial
    where could we define the persistance_unit when we remove persistance.xml file?

    • Amara Bargougui

      I think i found the answer :

      this should be the solution:

      cf : JAVADOC :
      getPersistenceUnitName() :

      Return the name of the persistence unit used to create this EntityManagerFactory, or null if it is an unnamed default.

  • Tomasz Biniecki

    Right in time. Spent 3 hours yesterday on JPA. The problem is it works all fine on local machine when I do spring rest and everything is configured through Application.java and annotations. As soon I started moving towards configuring servlet through xml and writing persistence.xml it all started falling apart.

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

      Happy the article helped. Cheers,
      Eugen.

  • James Lewis

    Thanks Eugen. This article and the sample project saved me a lot of time figuring out how go ds.xml and persistence.xml less with a WAR in JBoss. Very helpful.

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

      Happy to help James. Cheers,
      Eugen.

  • Mark Jochum

    Using the code samples in the article, I noticed that the bean method “transactionManager” from section 2 takes an EntityManagerFactory directly. The comment at the end of section 3 indicates that perhaps transactionManager should request the injection of a LocalContainerEntityManagerFactoryBean, is that the case? Great article, thanks for the post!

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

      Hey Mark – by injecting the EntityManagerFactory directly, Spring is actually going to use the factory bean to create the dependency under the hood – so you don’t need to. Hope that helps. Cheers,
      Eugen.

  • Imran Qureshi

    good article, straight forward and to the point.

  • http://www.facitech.com Maoan Zhou

    Very nice tutorial, I just have a question, how to load the class PersistenceJPAConfig?

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

      There are several way to bootstrap the Spring context. If you’re dealing with a standard web app, you can check out the web.xml portion in this article for the bootstrapping part. Cheers,
      Eugen.