Ръководство за JPA с пролетта

1. Общ преглед

Този урок показва как да настроите Spring с JPA , като използвате Hibernate като доставчик на постоянство.

За стъпка по стъпка за въвеждане на контекста на Spring, използвайки Java-базирана конфигурация и основния Maven pom за проекта, вижте тази статия.

Ще започнем с настройването на JPA в проект Spring Boot, след което ще разгледаме пълната конфигурация, от която се нуждаем, ако имаме стандартен проект Spring.

Ето видео за настройка на Hibernate 4 с Spring 4 (препоръчвам да го гледате в пълен 1080p):

2. JPA в Spring Boot

Проектът Spring Boot има за цел да направи създаването на Spring приложения много по-бързо и лесно. Това се прави с използването на стартери и автоматично конфигуриране за различни Spring функционалности, JPA сред тях.

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

За да активираме JPA в приложение Spring Spring, ни трябват зависимостите spring-boot-starter и spring-boot-starter-data-jpa :

 org.springframework.boot spring-boot-starter 2.2.6.RELEASE   org.springframework.boot spring-boot-starter-data-jpa 2.2.6.RELEASE 

В пролетно-обувка стартера съдържа необходимата авто-конфигурация за пролетта на СПА. Също така проектът spring-boot-starter-jpa препраща към всички необходими зависимости като hibernate-core .

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

Spring Boot конфигурира Hibernate като JPA доставчик по подразбиране , така че вече не е необходимо да дефинираме обекта entityManagerFactory, освен ако не искаме да го персонализираме.

Spring Boot също може автоматично да конфигурира зърното dataSource , в зависимост от базата данни, която използваме . В случай на база данни в паметта от тип H2 , HSQLDB и Apache Derby , Boot автоматично конфигурира DataSource, ако съответната зависимост от базата данни присъства на пътя на класа.

Например, ако искаме да използваме база данни H2 в паметта в JPA приложение Spring Boot, трябва само да добавим зависимостта h2 към файла pom.xml :

 com.h2database h2 1.4.200 

По този начин не е необходимо да дефинираме зърното 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 , но с Spring Boot 2 той е променен на HikariCP .

Можете да намерите още примери за конфигуриране на JPA в Spring Boot в проекта GitHub.

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

Ако обаче имаме стандартен проект Spring, тогава се нуждаем от по-ясна конфигурация, използвайки Java или XML. На това ще се спрем в следващите раздели.

3. Пролетната конфигурация на JPA с Java - в не-стартиращ проект

За да използваме JPA в пролетен проект, трябва да настроим EntityManager.

Това е основната част от конфигурацията и можем да го направим чрез фабричен боб Spring. Това може да бъде или по-простият LocalEntityManagerFactoryBean, или по-гъвкавият LocalContainerEntityManagerFactoryBean .

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

@Configuration @EnableTransactionManagement public class PersistenceJPAConfig{ @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource()); em.setPackagesToScan(new String[] { "com.baeldung.persistence.model" }); JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); em.setJpaVendorAdapter(vendorAdapter); em.setJpaProperties(additionalProperties()); return em; } // ... }

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

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

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

@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. The JPA Spring Configuration With XML

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

        create-drop org.hibernate.dialect.MySQL5Dialect              

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.

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:

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

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:

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

6. The Maven Configuration

In addition to the 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:

 org.hibernate hibernate-core 5.2.17.Final runtime   mysql mysql-connector-java 8.0.19 runtime 

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

7. Conclusion

Този урок илюстрира как да конфигурирате JPA с хибернация през пролетта както в Spring Boot, така и в стандартно приложение Spring.

Както винаги, кодът, представен в тази статия, е достъпен в GitHub.