Le DAO avec JPA et Spring

1. Vue d'ensemble

Cet article montrera comment implémenter le DAO avec Spring et JPA . Pour la configuration JPA principale, consultez l'article sur JPA avec Spring.

2. Plus de modèles de printemps

Depuis Spring 3.1, le JpaTemplate et le JpaDaoSupport correspondant ont été abandonnés au profit de l'utilisation de l'API Java Persistence native.

De plus, ces deux classes ne sont pertinentes que pour JPA 1 (à partir du javadoc JpaTemplate ):

Notez que cette classe n'a pas été mise à niveau vers JPA 2.0 et ne le sera jamais.

Par conséquent, il est désormais recommandé d' utiliser directement l'API Java Persistence au lieu du JpaTemplate .

2.1. Traduction d'exceptions sans le modèle

L'une des responsabilités de JpaTemplate était la traduction d'exceptions - la traduction des exceptions de bas niveau en exceptions Spring génériques de niveau supérieur.

Sans le modèle, la traduction d'exceptions est toujours activée et entièrement fonctionnelle pour tous les DAO annotés avec @Repository . Spring implémente cela avec un postprocesseur de bean qui conseillera tous les beans @Repository avec tous les PersistenceExceptionTranslator trouvés dans le conteneur.

Il est également important de noter que le mécanisme de traduction d'exceptions utilise des proxies - pour que Spring puisse créer des proxies autour des classes DAO, ceux-ci ne doivent pas être déclarés définitifs .

3. Le DAO

Tout d'abord, nous allons implémenter la couche de base pour tous les DAO - une classe abstraite utilisant des génériques et conçue pour être étendue:

public abstract class AbstractJpaDAO { private Class clazz; @PersistenceContext EntityManager entityManager; public final void setClazz( Class clazzToSet ){ this.clazz = clazzToSet; } public T findOne( long id ){ return entityManager.find( clazz, id ); } public List 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 ); } }

Le principal aspect intéressant ici est la façon dont l' EntityManager est injecté - en utilisant l' annotation standard @PersistenceContext . Sous le capot, cela est géré par le PersistenceAnnotationBeanPostProcessor - qui traite l'annotation, récupère le gestionnaire d'entités JPA du contient et l'injecte.

Le post-processeur de persistance est soit créé explicitement en le définissant dans la configuration, soit automatiquement, en définissant context: annotation-config ou context: component-scan dans la configuration de l'espace de noms.

Notez également que la classe d' entité est passée dans le constructeur pour être utilisée dans les opérations génériques:

@Repository public class FooDAO extends AbstractJPADAO implements IFooDAO{ public FooDAO(){ setClazz(Foo.class ); } }

4. Conclusion

Ce didacticiel a illustré comment configurer une couche DAO avec Spring et JPA , en utilisant à la fois une configuration basée sur XML et Java. Nous avons également expliqué pourquoi ne pas utiliser le JpaTemplate et comment le remplacer par EntityManager . Le résultat final est une implémentation DAO légère et propre, avec presque aucune dépendance au moment de la compilation sur Spring.

La mise en œuvre de ce projet simple peut être trouvée dans le projet GitHub - il s'agit d'un projet basé sur Maven, il devrait donc être facile à importer et à exécuter tel quel.