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

DAO с JPA и Spring

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

1. Обзор

В этой статье будет показано, как реализовать DAO с помощью Spring и JPA . Для базовой конфигурации JPA см . статью о JPA с Spring.

2. Больше никаких весенних шаблонов

Начиная с Spring 3.1, JpaTemplate и соответствующий JpaDaoSupport устарели в пользу использования собственного Java Persistence API .

Кроме того, оба этих класса относятся только к JPA 1 (из javadoc JpaTemplate ):

Обратите внимание, что этот класс не был обновлен до JPA 2.0 и никогда не будет обновлен.

Как следствие, сейчас лучше всего использовать Java Persistence API напрямую , а не JpaTemplate .

2.1. Перевод исключений без шаблона

Одной из обязанностей JpaTemplate была трансляция исключений — перевод исключений низкого уровня в общие исключения Spring более высокого уровня.

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

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

3. ДАО

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

public abstract class AbstractJpaDAO< T extends Serializable > {

private Class< T > clazz;

@PersistenceContext
EntityManager entityManager;

public final void setClazz( Class< T > clazzToSet ){
this.clazz = clazzToSet;
}

public T findOne( long id ){
return entityManager.find( clazz, id );
}
public List< T > findAll(){
return entityManager.createQuery( "from " + clazz.getName() )
.getResultList();
}

public void create( T entity ){
entityManager.persist( entity );
}

public T update( T entity ){
return entityManager.merge( entity );
}

public void delete( T entity ){
entityManager.remove( entity );
}
public void deleteById( long entityId ){
T entity = findOne( entityId );
delete( entity );
}
}

Основным интересным аспектом здесь является способ внедрения EntityManager с использованием стандартной аннотации @PersistenceContext . Под капотом это обрабатывается PersistenceAnnotationBeanPostProcessor , который обрабатывает аннотацию, извлекает диспетчер сущностей JPA из содержимого и внедряет его.

Постпроцессор персистентности создается либо явно, определяя его в конфигурации, либо автоматически, определяя context:annotation-config или context:component-scan в конфигурации пространства имен.

Также обратите внимание, что класс сущности передается в конструктор для использования в общих операциях:

@Repository
public class FooDAO extends AbstractJPADAO< Foo > implements IFooDAO{

public FooDAO(){
setClazz(Foo.class );
}
}

4. Вывод

В этом руководстве показано , как настроить уровень DAO с помощью Spring и JPA , используя конфигурацию на основе XML и Java. Мы также обсудили, почему не использовать JpaTemplate и как заменить его на EntityManager . Конечным результатом является легкая, чистая реализация DAO, практически не зависящая от Spring во время компиляции.

Реализацию этого простого проекта можно найти в проекте GitHub — это проект на основе Maven, поэтому его легко импортировать и запускать как есть.