Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

NPI – JPA Buddy – JPA (partner)
announcement - icon

JPA is huge! It covers nearly every aspect of communication between relational databases and the Java application and is deeply integrated into all major frameworks.

If you're using IntelliJ, JPA Buddy is super helpful. The plugin gently guides you through the subtleties of the most popular JPA implementations, visually reminds you of JPA features, generates code that follows best practices, and integrates intelligent inspections to improve your existing persistence code.

More concretely, it provides powerful tooling to generate Spring Data JPA repositories and methods, Flyway Versioned Migrations, Liquibase Differential Changelogs, DDL and SQL statements, DTO objects, and MapStruct interfaces.

Oh, and it actually generates JPA entities from an existing database and gradually update the data model as the database evolves! Yeah.

>> Become a lot more productive with JPA Buddy

November Discount Launch 2022 – Top
We’re finally running a Black Friday launch. All Courses are 30% off until next Friday:


November Discount Launch 2022 – TEMP TOP (NPI)
We’re finally running a Black Friday launch. All Courses are 30% off until next Friday:


Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

1. Overview

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

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

We'll start by setting up JPA in a Spring Boot project. Then we'll look into the full configuration we need if we have a standard Spring project.

Further reading:

Defining JPA Entities

Learn how to define entities and customize them using the Java Persistence API.

Spring Boot with Hibernate

A quick, practical intro to integrating Spring Boot and Hibernate/JPA.

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

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

2.1. Maven Dependencies

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


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

2.2. Configuration

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 we're using. 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:


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

If we want to use JPA with MySQL database, we need the mysql-connector-java dependency. We'll also need to define the DataSource configuration.

We can do this 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:

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

    return dataSource;

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


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

Also in Spring Boot 1, the default connection pool was Tomcat, but it has been changed to HikariCP with Spring Boot 2.

We have more examples of configuring JPA in Spring Boot in the GitHub project.

As we can see, the basic JPA configuration is fairly simple if we're using Spring Boot.

However, if we have a standard Spring project, we need more explicit configuration, using either Java or XML. That's what we'll focus on in the next sections.

3. The JPA Spring Configuration With Java in a Non-Boot Project

To use JPA in a Spring project, we need to set up the EntityManager.

This is the main part of the configuration, and we can do it via a Spring factory bean. This can be either the simpler LocalEntityManagerFactoryBean or the more flexible LocalContainerEntityManagerFactoryBean.

Let's see how we can use the latter option:

public class PersistenceJPAConfig{

   public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
      LocalContainerEntityManagerFactoryBean em 
        = new LocalContainerEntityManagerFactoryBean();
      em.setPackagesToScan(new String[] { "com.baeldung.persistence.model" });

      JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();

      return em;
   // ...


We also need to explicitly define the DataSource bean we've used above:

public DataSource dataSource(){
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setUsername( "tutorialuser" );
    dataSource.setPassword( "tutorialmy5ql" );
    return dataSource;

The final part of the configuration is the additional Hibernate properties and the TransactionManager and exceptionTranslation beans:

public PlatformTransactionManager transactionManager() {
    JpaTransactionManager transactionManager = new JpaTransactionManager();

    return transactionManager;

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;

4. JPA Spring Configuration With XML

Next, let's see the same Spring configuration with XML:

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

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

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

There's a relatively small difference between the XML and the new Java-based configuration. Namely, in XML, a reference to another bean can point to either the bean or a bean factory for that bean.

But in Java, 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:


5. 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 we need to remove. We can now set up JPA fully with no XML.

We would usually specify JPA properties in the persistence.xml file.

Alternatively, we can add the properties directly to the entity manager factory bean:


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

6. The Maven Configuration

In addition to the Spring Core and persistence dependencies — shown 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:



Note that the MySQL dependency is included here as an example. We need a driver to configure the data source, but any Hibernate-supported database will do.

7. Conclusion

This tutorial illustrated how to configure JPA with Hibernate in Spring in both a Spring Boot and a standard Spring application.

As always, the code presented in this article is available over on GitHub.

November Discount Launch 2022 – Bottom
We’re finally running a Black Friday launch. All Courses are 30% off until next Friday:


Persistence footer banner
Comments are closed on this article!