Le DAO avec JPA et Spring

Le DAO avec JPA et Spring

1. Vue d'ensemble

Cet article montrera commentimplement the DAO with Spring and JPA. Pour la configuration JPA principale, consultezthe article about JPA avec Spring.

2. Plus de modèles de printemps

À partir de Spring 3.1, lesJpaTemplate et lesJpaDaoSupporthave beencorrespondants sont obsolètes 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 javadocJpaTemplate):

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'utiliseruse the Java Persistence API directly au lieu desJpaTemplate.

2.1. Traduction d'exceptions sans le modèle

L'une des responsabilités deJpaTemplate étaitexception translation - traduisant les exceptions de bas niveau en exceptions Spring génériques de niveau supérieur.

Sans le modèle,exception translation is still enabled and fully functional pour tous les DAO annotés avec@Repository. Spring implémente cela avec un postprocesseur de bean qui informera tous les beans@Repository avec tous lesPersistenceExceptionTranslator trouvés dans le conteneur.

Il est également important de noter quethe exception translation mechanism uses proxies - pour que Spring puisse créer des proxies autour des classes DAO, ceux-ci ne doivent pas être déclarésfinal.

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

Le principal aspect intéressant ici est la façon dontthe EntityManager is injected - utilise l'annotation standard@PersistenceContext. Sous le capot, cela est géré par lePersistenceAnnotationBeanPostProcessor - 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éfinissantcontext:annotation-config oucontext:component-scan dans la configuration de l'espace de noms.

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

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

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

4. Conclusion

Ce didacticiel a illustréhow to set up a DAO layer with Spring and JPA, en utilisant à la fois une configuration XML et Java. Nous avons également discuté pourquoi ne pas utiliser lesJpaTemplate et comment les remplacer par lesEntityManager. Le résultat final est une implémentation DAO légère et propre, ne dépendant presque pas de Spring lors de la compilation.

L'implémentation de ce projet simple peut être trouvée dansthe GitHub project - il s'agit d'un projet basé sur Maven, il devrait donc être facile à importer et à exécuter tel quel.