O DAO com JPA e Spring

O DAO com JPA e Spring

1. Visão geral

Este artigo mostrará comoimplement the DAO with Spring and JPA. Para a configuração principal do JPA, consultethe article about JPA com Spring.

2. Não há mais modelos de primavera

A partir do Spring 3.1, oJpaTemplate e oJpaDaoSupporthave been correspondente tornaram-se obsoletos em favor do uso da API de persistência Java nativa.

Além disso, ambas as classes são relevantes apenas para JPA 1 (do javadocJpaTemplate):

Observe que esta classe não foi atualizada para o JPA 2.0 e nunca será.

Como consequência, agora é a melhor práticause the Java Persistence API directly em vez deJpaTemplate.

2.1. Tradução de exceção sem o modelo

Uma das responsabilidades deJpaTemplate eraexception translation - traduzindo as exceções de baixo nível em um nível mais alto, exceções genéricas do Spring.

Sem o modelo,exception translation is still enabled and fully functional para todos os DAOs anotados com@Repository. O Spring implementa isso com um pós-processador de bean que avisará todos os beans@Repository com todos osPersistenceExceptionTranslator encontrados no Container.

Também é importante observar quethe exception translation mechanism uses proxies - para que o Spring possa criar proxies em torno das classes DAO, eles não devem ser declaradosfinal.

3. O DAO

Primeiro, vamos implementar a camada de base para todos os DAOs - uma classe abstrata usando genéricos e projetada para ser estendida:

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

O principal aspecto interessante aqui é a forma comothe EntityManager is injected - usando a anotação padrão@PersistenceContext. Nos bastidores, isso é tratado peloPersistenceAnnotationBeanPostProcessor - que processa a anotação, recupera o gerenciador de entidade JPA do contém e o injeta.

O pós-processador de persistência é criado explicitamente definindo-o na configuração ou automaticamente, definindocontext:annotation-config oucontext:component-scan na configuração do namespace.

Além disso, observe que a entidadeClass é passada no construtor para ser usada nas operações genéricas:

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

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

4. Conclusão

Este tutorial ilustrouhow to set up a DAO layer with Spring and JPA, usando XML e configuração baseada em Java. Também discutimos por que não usar oJpaTemplate e como substituí-lo peloEntityManager. O resultado final é uma implementação leve e limpa do DAO, com quase nenhuma dependência do Spring em tempo de compilação.

A implementação deste projeto simples pode ser encontrada emthe GitHub project - este é um projeto baseado em Maven, portanto, deve ser fácil de importar e executar como está.