The Java Persistence API is a standard technology that allows you to "map" objects to relational databases. The spring-boot-starter-data-jpa
POM model allows you to get started quickly. It provides the following key dependencies:
-
Hibernate is one of the most popular JPA implementations.
-
Spring Data JPA: Helps implement JPA-based repositories.
-
Spring ORM: The primary ORM support tool from the Spring Framework.
Traditionally, JPA "entity" classes are defined in the persistence.xml
file. In Spring Boot, this file is not required; Entity Scanning is used instead. By default, the search is performed in all packages below the main configuration class (the one annotated with @EnableAutoConfiguration
or @SpringBootApplication
).
Any classes annotated with @Entity
, @Embeddable
or @MappedSuperclass
are taken into account. A typical entity class looks like the following example:
@Entity public class City implements Serializable { @Id @GeneratedValue private Long id; @Column(nullable = false) private String name; @Column(nullable = false) private String state; // ... additional members, often containing @OneToMany annotation mappings protected City() { // no-argument constructor required by the JPA specification // protected because it's not meant to be used directly } public City(String name, String state) { this.name = name; this.state = state; } public String getName() { return this.name; } public String getState() { return this.state; } // ... etc. }
@Entity class City : Serializable { @Id @GeneratedValue private val id: Long? = null @Column(nullable = false) var name: String? = null private set // ... etc. @Column(nullable = false) var state: String? = null private set // ... additional members, often containing @OneToMany annotation mappings protected constructor() { // no-argument constructor required by the JPA specification // protected because it's not meant to be used directly } constructor(name: String?, state: String?) { this.name = name this.state = state } }
@EntityScan
annotation.
Spring Data JPA Repositories
Spring Data JPA repositories are interfaces that can be defined to access data. JPA queries are created automatically based on method names. For example, the CityRepository
interface might declare a findAllByState(String state)
method to find all cities in a given state.
For more complex queries, you can annotate the method using the Query
annotation from Spring Data.
Spring Data repositories are typically extended using the Repository
or CrudRepository
interfaces. If you use autoconfiguration, the repositories are searched from the package containing the main configuration class (the one annotated with @EnableAutoConfiguration
or @SpringBootApplication
) and down the hierarchy.
The following example shows a typical interface definition for interacting with a Spring Data repository:
public interface CityRepository extends Repository<City, Long> { Page<City> findAll(Pageable pageable); City findByNameAndStateAllIgnoringCase(String name, String state); }
interface CityRepository : Repository<City?, Long?> { fun findAll(pageable: Pageable?): Page<City?>? fun findByNameAndStateAllIgnoringCase(name: String?, state: String?): City? }
Spring Data JPA repositories support three different bootstrap modes: default, delayed, and lazy. To enable deferred loading or lazy loading, set the spring.data.jpa.repositories.bootstrap-mode
property to deferred
or lazy
respectively. When lazy loading or delayed loading, the autoconfigured EntityManagerFactoryBuilder
will use the context's AsyncTaskExecutor
, if present, as the load executor. If there is more than one executor, the one named applicationTaskExecutor
will be used.
When using delayed loading or lazy loading, you should ensure that access to the JPA infrastructure is provided with a delay after the application context initial loading stage. You can use SmartInitializingSingleton
to call any initialization that requires the JPA framework. For JPA components (such as converters) that are instantiated as Spring beans, use ObjectProvider
to defer dependency resolution, if any.
Spring Data Envers Repositories
If Spring Data Envers is available, JPA repositories will be automatically configured to support typical Envers queries.
To use Spring Data Envers, ensure that the repository is extended from RevisionRepository
, as shown in the following example:
public interface CountryRepository extends RevisionRepository<Country, Long, Integer>, Repository<Country, Long> { Page<Country> findAll(Pageable pageable); }
interface CountryRepository : RevisionRepository<Country?, Long?, Int>, Repository<Country?, Long?> { fun findAll(pageable: Pageable?): Page<Country?>? }
Creating and deleting JPA databases
By default, JPA databases are created automatically only if you use an embedded database (H2, HSQL or Derby). You can explicitly configure JPA settings using the spring.jpa.*
properties. For example, to create and delete tables, you can add the following line to application.properties
:
spring.jpa.hibernate.ddl-auto=create-drop
spring:
jpa:
hibernate.ddl-auto: "create-drop"
hibernate.hbm2ddl.auto
. You can set it along with other native Hibernate properties using
spring.jpa.properties.*
(the prefix is removed before adding it to the entity manager). The following line shows an example of setting JPA properties for Hibernate:
spring.jpa.properties.hibernate[globally_quoted_identifiers]=true
spring:
jpa:
properties:
hibernate:
"globally_quoted_identifiers": "true"
The line in the previous example passes the value true
for the hibernate.globally_quoted_identifiers
property to the Hibernate entity manager.
By default, DDL execution (or validation) is deferred until the ApplicationContext
is launched. There is also a spring.jpa.generate-ddl
flag, but it is not used if Hibernate autoconfiguration is active, since the ddl-auto
settings are more precise.
Opening EntityManager in a View
If you are running a web application, Spring Boot by default registers OpenEntityManagerInViewInterceptor
to apply the Open EntityManager in View pattern to enable lazy loading in web views. If you do not require this operating logic, then you should set spring.jpa.open-in-view
to false
in application.properties
.
GO TO FULL VERSION