DAO с JPA и весной

DAO с JPA и весной

1. обзор

Эта статья покажет, какimplement the DAO with Spring and JPA. Для базовой конфигурации JPA см.the article about JPA с Spring.

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

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

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

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

Как следствие, теперь рекомендуется использоватьuse the Java Persistence API directly вместоJpaTemplate.

2.1. Исключительный перевод без шаблона

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

Без шаблонаexception translation is still enabled and fully functional для всех DAO, аннотированных@Repository. Spring реализует это с помощью постпроцессора bean, который сообщит всем bean-компонентам@Repository всеPersistenceExceptionTranslator, найденные в контейнере.

Также важно отметить, чтоthe exception translation mechanism uses proxies - чтобы Spring мог создавать прокси вокруг классов DAO, их нельзя объявлятьfinal.

3. DAO

Во-первых, мы реализуем базовый уровень для всех 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 );
   }
}

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

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

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

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

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

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

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

Реализацию этого простого проекта можно найти вthe GitHub project - это проект на основе Maven, поэтому его должно быть легко импортировать и запускать как есть.