Перейти к основному содержимому

Руководство по JPA с Spring

· 6 мин. чтения

1. Обзор

В этом руководстве показано, как настроить Spring с JPA , используя Hibernate в качестве поставщика постоянства.

Пошаговое введение в настройку контекста Spring с использованием конфигурации на основе Java и базовой помпы Maven для проекта см . в этой статье .

Мы начнем с настройки JPA в проекте Spring Boot. Затем мы рассмотрим полную конфигурацию, которая нам нужна, если у нас есть стандартный проект Spring.

Вот видео по настройке Hibernate 4 с Spring 4 (рекомендуем посмотреть его в полном 1080p):

iFrame should be here.

2. JPA в Spring Boot

Проект Spring Boot предназначен для того, чтобы сделать создание приложений Spring намного быстрее и проще. Это делается с использованием стартеров и автоматической настройки для различных функций Spring, в том числе JPA.

2.1. Зависимости Maven

Чтобы включить JPA в приложении Spring Boot, нам нужны зависимости spring-boot-starter и spring-boot-starter-data-jpa :

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

Spring - boot-starter содержит необходимую автоматическую настройку для Spring JPA. Кроме того, проект spring-boot-starter-jpa ссылается на все необходимые зависимости, такие как hibernate-core .

2.2. Конфигурация

Spring Boot настраивает Hibernate в качестве поставщика JPA по умолчанию , поэтому больше нет необходимости определять bean- компонент entityManagerFactory , если только мы не хотим его настраивать.

Spring Boot также может автоматически настраивать bean- компонент dataSource в зависимости от используемой базы данных. В случае базы данных в памяти типа H2 , HSQLDB и Apache Derby Boot автоматически настраивает DataSource , если соответствующая зависимость базы данных присутствует в пути к классам.

Например, если мы хотим использовать базу данных H2 в памяти в приложении Spring Boot JPA, нам нужно всего лишь добавить зависимость h2 в файл pom.xml :

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

Таким образом, нам не нужно определять bean- компонент dataSource , но мы можем это сделать, если захотим его настроить.

Если мы хотим использовать JPA с базой данных MySQL , нам нужна зависимость mysql-connector-java . Нам также потребуется определить конфигурацию DataSource .

Мы можем сделать это в классе @Configuration или с помощью стандартных свойств Spring Boot.

Конфигурация Java выглядит так же, как в стандартном проекте Spring:

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

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

return dataSource;
}

Чтобы настроить источник данных с помощью файла свойств, мы должны установить свойства с префиксом spring.datasource :

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

Spring Boot автоматически настроит источник данных на основе этих свойств.

Также в Spring Boot 1 пулом соединений по умолчанию был Tomcat , но он был изменен на HikariCP с Spring Boot 2.

Еще примеры настройки JPA в Spring Boot у нас есть в проекте GitHub .

Как мы видим, базовая конфигурация JPA довольно проста, если мы используем Spring Boot.

Однако, если у нас есть стандартный проект Spring, нам нужна более явная конфигурация с использованием Java или XML. Это то, на чем мы сосредоточимся в следующих разделах.

3. Конфигурация JPA Spring с Java в незагрузочном проекте

Чтобы использовать JPA в проекте Spring, нам нужно настроить EntityManager .

Это основная часть конфигурации, и мы можем сделать это с помощью фабричного компонента Spring. Это может быть либо более простой LocalEntityManagerFactoryBean, либо более гибкий LocalContainerEntityManagerFactoryBean .

Давайте посмотрим, как мы можем использовать последний вариант:

@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig{

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em
= new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "com.foreach.persistence.model" });

JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());

return em;
}

// ...

}

Нам также необходимо явно определить bean -компонент DataSource , который мы использовали выше:

@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;
}

Последняя часть конфигурации — это дополнительные свойства Hibernate и bean-компоненты TransactionManager и exceptionTranslation :

@Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());

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;
}

4. Конфигурация JPA Spring с XML

Далее давайте посмотрим на ту же конфигурацию Spring с XML:

<bean id="myEmf" 
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.foreach.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" />

Существует относительно небольшая разница между XML и новой конфигурацией на основе Java. А именно, в XML ссылка на другой бин может указывать либо на бин, либо на фабрику бинов для этого бина.

Но в Java, поскольку типы разные, компилятор не позволяет этого, поэтому EntityManagerFactory сначала извлекается из фабрики компонентов, а затем передается менеджеру транзакций:

transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());

5. Полностью отказаться от XML

Обычно JPA определяет единицу персистентности через файл META-INF/persistence.xml . Начиная с Spring 3.1 файл persistence.xml больше не нужен. LocalContainerEntityManagerFactoryBean теперь поддерживает свойство packagesToScan , в котором можно указать пакеты для сканирования на наличие классов @Entity .

Этот файл был последним фрагментом XML, который нам нужно удалить. Теперь мы можем полностью настроить JPA без XML.

Обычно мы указываем свойства JPA в файле persistence.xml .

В качестве альтернативы мы можем добавить свойства непосредственно в компонент фабрики диспетчера сущностей:

factoryBean.setJpaProperties(this.additionalProperties());

В качестве примечания: если Hibernate является поставщиком постоянства, это также может быть способом указать свойства, специфичные для Hibernate.

6. Конфигурация Maven

В дополнение к зависимостям Spring Core и постоянства, подробно показанным в руководстве Spring with Maven , нам также необходимо определить JPA и Hibernate в проекте, а также коннектор MySQL:

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.17.Final</version>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
<scope>runtime</scope>
</dependency>

Обратите внимание, что зависимость MySQL включена здесь в качестве примера. Нам нужен драйвер для настройки источника данных, но подойдет любая база данных с поддержкой Hibernate.

7. Заключение

В этом руководстве показано, как настроить JPA с Hibernate в Spring как в Spring Boot, так и в стандартном приложении Spring.

Как всегда, код, представленный в этой статье, доступен на GitHub .