29.3 JPA and ‘Spring Data’
The Java Persistence API is a standard technology that allows you to ‘map’ objects to relational databases. The spring-boot-starter-data-jpa
POM provides a quick way to get started. It provides the following key dependencies:
- Hibernate — One of the most popular JPA implementations.
- Spring Data JPA — Makes it easy to implement JPA-based repositories.
- Spring ORMs — Core ORM support from the Spring Framework.
Tip | |
---|---|
We won’t go into too many details of JPA or Spring Data here. You can follow the ‘Accessing Data with JPA’ guide from spring.io and read the Spring Data JPA and Hibernate reference documentation. |
Note | |
---|---|
By default, Spring Boot uses Hibernate 5.0.x. However it’s also possible to use 4.3.x or 5.2.x if you wish. Please refer to the Hibernate 4 and Hibernate 5.2 samples to see how to do so. |
29.3.1 Entity Classes
Traditionally, JPA ‘Entity’ classes are specified in a persistence.xml
file. With Spring Boot this file is not necessary and instead ‘Entity Scanning’ is used. By default all packages below your main configuration class (the one annotated with @EnableAutoConfiguration
or @SpringBootApplication
) will be searched.
Any classes annotated with @Entity
, @Embeddable
or @MappedSuperclass
will be considered. A typical entity class would look something like this:
package com.example.myapp.domain; import java.io.Serializable; import javax.persistence.*; _@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 include @OneToMany mappings protected City() { // no-args constructor required by JPA spec // this one is protected since it shouldn't be used directly } public City(String name, String state) { this.name = name; this.country = country; } public String getName() { return this.name; } public String getState() { return this.state; } // ... etc }
Tip | |
---|---|
You can customize entity scanning locations using the @EntityScan annotation. See the Section 74.4, “Separate @Entity definitions from Spring configuration” how-to. |
29.3.2 Spring Data JPA Repositories
Spring Data JPA repositories are interfaces that you can define to access data. JPA queries are created automatically from your method names. For example, a CityRepository
interface might declare a findAllByState(String state)
method to find all cities in a given state.
For more complex queries you can annotate your method using Spring Data’s Query
annotation.
Spring Data repositories usually extend from the Repository
or CrudRepository
interfaces. If you are using auto-configuration, repositories will be searched from the package containing your main configuration class (the one annotated with @EnableAutoConfiguration
or @SpringBootApplication
) down.
Here is a typical Spring Data repository:
package com.example.myapp.domain; import org.springframework.data.domain.*; import org.springframework.data.repository.*; public interface CityRepository extends Repository<City, Long> { Page<City> findAll(Pageable pageable); City findByNameAndCountryAllIgnoringCase(String name, String country); }
Tip | |
---|---|
We have barely scratched the surface of Spring Data JPA. For complete details check their reference documentation. |
29.3.3 Creating and dropping JPA databases
By default, JPA databases will be automatically created only if you use an embedded database (H2, HSQL or Derby). You can explicitly configure JPA settings using spring.jpa.*
properties. For example, to create and drop tables you can add the following to your application.properties
.
spring.jpa.hibernate.ddl-auto=create-drop
Note | |
---|---|
Hibernate’s own internal property name for this (if you happen to remember it better) is hibernate.hbm2ddl.auto . You can set it, along with other Hibernate native properties, using spring.jpa.properties.* (the prefix is stripped before adding them to the entity manager). Example: |
spring.jpa.properties.hibernate.globally_quoted_identifiers=true
passes hibernate.globally_quoted_identifiers
to the Hibernate entity manager.
By default the DDL execution (or validation) is deferred until the ApplicationContext
has started. There is also a spring.jpa.generate-ddl
flag, but it is not used if Hibernate autoconfig is active because the ddl-auto
settings are more fine-grained.