I usually post about Persistence on Twitter - 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.

NEW: Here is a video on setting up Hibernate 4 with Spring 4 (I recommend watching it in full 1080p):

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.cj.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.cj.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 its 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>5.2.10.Final</version>
   <scope>runtime</scope>
</dependency>

<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>6.0.6</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. JPA in Spring Boot

The Spring Boot project is intended to make creating Spring applications much faster and easier. This is done with the use of starters and auto-configuration for various Spring functionalities, JPA among them.

To enable JPA in a Spring Boot application, we need the spring-boot-starter and spring-boot-starter-data-jpa dependencies:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>1.5.3.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <version>1.5.3.RELEASE</version>
</dependency>

The spring-boot-starter contains the necessary auto-configuration for Spring JPA, and the spring-boot-starter-jpa project references all the necessary dependencies such as hibernate-entitymanager.

Spring Boot configures Hibernate as the default JPA provider, so it’s no longer necessary to define the entityManagerFactory bean unless we want to customize it.

Spring Boot can also auto-configure the dataSource bean, depending on the database used. In the case of an in-memory database of type H2, HSQLDB and Apache Derby, Boot automatically configures the DataSource if the corresponding database dependency is present on the classpath.

For example, if we want to use an in-memory H2 database in a Spring Boot JPA application, we only need to add the h2 dependency to the pom.xml file:

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.195</version>
</dependency>

This way, we don’t need to define the dataSource bean, but we can do so if we want to customize it.

If we want to use JPA with MySQL database, then we need the mysql-connector-java dependency, as well as to define the DataSource configuration.

This can be done in a @Configuration class, or by using standard Spring Boot properties.

The Java configuration looks the same as it does in a standard Spring project:

@Bean
public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();

    dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql://localhost:3306/myDb?createDatabaseIfNotExist=true");
    dataSource.setUsername("mysqluser");
    dataSource.setPassword("mysqlpass");

    return dataSource;
}

To configure the data source using a properties file, we have to set properties prefixed with spring.datasource:

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/myDb?createDatabaseIfNotExist=true
spring.datasource.username=mysqluser
spring.datasource.password=mysqlpass

Spring Boot will automatically configure a data source based on these properties.

You can find more examples of configuring JPA in Spring Boot in the GitHub project.

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

As always, the code presented in this article is available over on Github. This is a Maven based project, so it should be easy to import and run as it is.

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


Sort by:   newest | oldest | most voted
Gauthier Peel
Guest

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

Eugen Paraschiv
Guest

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
Guest

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 …

mwmahlberg
Guest

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
Guest

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

Excuse my English

Eugen Paraschiv
Guest

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
Guest

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?

Eugen Paraschiv
Guest

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
Guest

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.

Eugen Paraschiv
Guest

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.

Abhi
Guest

Hey Eugen

i wanted to connect two database in the project with this method
how do you think it is possible using this method

Rupanjan Baidya
Guest

Baeldung,

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

Thank you in advance.

Eugen Paraschiv
Guest

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.

wpDiscuz