Статьи

Уровень сохраняемости с данными Spring JPA

1. Обзор

Эта статья будет посвящена настройке и реализации уровня персистентности с использованием Spring 3.1, JPA и Spring Data . Пошаговое введение по настройке контекста Spring с использованием конфигурации на основе Java и базового Maven pom для проекта см. В этой статье .

Серия « Стойкость с весны » :

2. Больше никаких реализаций DAO

Как обсуждалось в предыдущей статье, уровень DAO обычно состоит из большого количества стандартного кода, который можно и нужно упростить. Преимущества такого упрощения многочисленны: уменьшение количества артефактов, которые необходимо определить и поддерживать, упрощение и согласованность шаблонов доступа к данным и согласованность конфигурации.

Spring Data делает это упрощение на один шаг вперед и позволяет полностью удалить реализации DAO — интерфейс DAO теперь является единственным артефактом, который необходимо явно определить.

3. Spring Data управляет DAO

Чтобы начать использовать модель программирования Spring Data с JPA, интерфейс DAO должен расширить интерфейс репозитория, специфичный для JPA — JpaRepository — в иерархии интерфейса Spring. Это позволит Spring Data найти этот интерфейс и автоматически создать для него реализацию.

Кроме того, расширяя интерфейс, мы получаем большинство, если не все соответствующие универсальные методы CRUD для стандартного доступа к данным, доступные в DAO.

4. Определение пользовательского метода доступа и запросов

Как уже говорилось, благодаря реализации одного из интерфейсов репозитория в DAO уже будут определены и реализованы некоторые базовые методы CRUD (и запросы). Чтобы определить более конкретные методы доступа, Spring JPA поддерживает довольно много опций — вы можете либо просто определить новый метод в интерфейсе, либо вы можете предоставить фактический запрос JPQ с помощью аннотации @Query .

Третий вариант определения пользовательских запросов — это использование именованных запросов JPA, но у него есть недостаток, заключающийся в том, что он либо включает XML, либо обременяет класс домена запросами.

В дополнение к этому Spring Data представляет более гибкий и удобный API, похожий на JPA Criteria API, только более читаемый и многократно используемый. Преимущества этого API станут более заметными при работе с большим количеством фиксированных запросов, которые потенциально могут быть более кратко выражены через меньшее количество повторно используемых блоков, которые продолжают встречаться в различных комбинациях.

4.1. Автоматические пользовательские запросы

Когда Spring Data создает новую реализацию репозитория , он анализирует все методы, определенные интерфейсами, и пытается автоматически генерировать запросы из имени метода . Хотя это имеет ограничения, это очень мощный и элегантный способ определения новых пользовательских методов доступа с минимальными усилиями.

Например, если управляемый объект имеет поле имени (а также стандартный метод получения и установки Java Bean для этого поля), определение метода findByName в интерфейсе DAO автоматически сгенерирует правильный запрос:

1
2
3
4
5
public interface IFooDAO extends JpaRepository< Foo, Long >{
 
   Foo findByName( final String name );
 
}

Это относительно простой пример; гораздо больший набор ключевых слов поддерживается механизмом создания запросов.

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

java.lang.IllegalArgumentException: не найдено имя свойства для класса типа org.rest.model.Foo

4.2. Ручные пользовательские запросы

Помимо получения запроса по имени метода, пользовательский запрос можно указать вручную с помощью аннотации уровня @Query .

Для еще более детального контроля над созданием запросов, таких как использование именованных параметров или изменение существующих запросов, ссылка является хорошим местом для начала.

5. Конфигурация транзакции Spring Data

Фактическая реализация управляемого DAO Spring Data — SimpleJpaRepository — использует аннотации для определения и настройки транзакций . Только для чтения @Transactional аннотация используется на уровне класса, который затем переопределяется для не только для чтения методов. Остальная семантика транзакции используется по умолчанию, но ее можно легко переопределить вручную для каждого метода.

5.1. Исключение перевода без шаблона

Одной из обязанностей шаблонов Spring ORM ( JpaTemplate , HibernateTemplate ) является преобразование исключений — перевод исключений JPA — которые связывают API с JPA — с иерархией SpringAA DataException .

Без этого шаблона преобразование исключений можно включить, пометив DAO аннотацией @Repository . Это, в сочетании с постпроцессором bean-компонента Spring, будет советовать всем bean- компонентам @Repository со всеми реализациями PersistenceExceptionTranslator, найденными в контейнере, предоставлять перевод исключений без использования шаблона.

Тот факт, что преобразование исключений действительно активно, можно легко проверить с помощью интеграционного теста :

1
2
3
4
5
6
@Test( expected = DataAccessException.class )
public void whenAUniqueConstraintIsBroken_thenSpringSpecificExceptionIsThrown(){
   String name = "randomName";
   service.save( new Foo( name ) );
   service.save( new Foo( name ) );
}

Перевод исключений осуществляется через прокси; чтобы Spring мог создавать прокси вокруг классов DAO, они не должны быть объявлены как final .

6. Spring Data Configuration

Чтобы активировать поддержку репозитория Spring JPA, пространство имен jpa определено и используется для указания пакета, в котором расположены интерфейсы DAO:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<beans
   xsi:schemaLocation="
 
<jpa:repositories base-package="org.rest.dao.spring" />
 
</beans>

На данный момент не существует эквивалентной конфигурации на основе Java — однако ее поддержка находится в разработке .

7. Настройка Spring Java или XML

В предыдущей статье этой серии уже подробно обсуждалось, как настроить JPA в Spring 3 . Spring Data также использует поддержку Spring для аннотации JPA @PersistenceContext, которую он использует для связывания EntityManager с фабричным компонентом Spring, отвечающим за создание реальных реализаций DAO — JpaRepositoryFactoryBean .

В дополнение к уже обсужденной конфигурации, есть еще один последний отсутствующий элемент, включая конфигурацию Spring Data XML в общей конфигурации постоянства:

1
2
3
4
5
6
@Configuration
@EnableTransactionManagement
@ImportResource( "classpath*:*springDataConfig.xml" )
public class PersistenceJPAConfig{
   ...
}

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

В дополнение к конфигурации Maven для JPA, определенной в предыдущей статье , добавлена ​​зависимость spring-data-jpa :

1
2
3
4
5
<dependency>
   <groupId>org.springframework.data</groupId>
   <artifactId>spring-data-jpa</artifactId>
   <version>1.3.2.RELEASE</version>
</dependency>

9. Вывод

В этой статье рассказывается о настройке и реализации уровня персистентности в Spring 3.1, JPA 2 и Spring JPA (часть зонтичного проекта Spring Data) с использованием конфигурации на основе XML и Java. Обсуждаются различные методы определения более сложных пользовательских запросов , а также конфигурация с новым пространством имен jpa и транзакционной семантикой. Конечным результатом является новый и элегантный подход к доступу к данным в Spring, практически не требующий практической реализации. Вы можете проверить полную реализацию в проекте github .

Ссылка: Уровень сохраняемости с данными Spring JPA от нашего партнера JCG Евгения Параскива в блоге baeldung .