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, поэтому его легко импортировать и запускать как есть.