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á.