web-dev-qa-db-fra.com

Méthodes DAO uniques et CRUD génériques (JPA / Hibernate + Spring)

Suite à ma question précédente, DAO et couches de service (JPA/Hibernate + Spring) , j'ai décidé d'utiliser un seul DAO pour ma couche de données (au moins au début) dans une application utilisant JPA/Hibernate , Spring et Wicket. L'utilisation de méthodes génériques CRUD a été proposée, mais je ne sais pas trop comment l'implémenter en utilisant JPA. Pourriez-vous s'il vous plaît me donner un exemple ou partager un lien à ce sujet?

45
John Manak

Voici un exemple d'interface:

public interface GenericDao<T, PK extends Serializable> {
    T create(T t);
    T read(PK id);
    T update(T t);
    void delete(T t);
}

Et une implémentation:

public class GenericDaoJpaImpl<T, PK extends Serializable> 
    implements GenericDao<T, PK> {

    protected Class<T> entityClass;

    @PersistenceContext
    protected EntityManager entityManager;

    public GenericDaoJpaImpl() {
        ParameterizedType genericSuperclass = (ParameterizedType) getClass()
             .getGenericSuperclass();
        this.entityClass = (Class<T>) genericSuperclass
             .getActualTypeArguments()[0];
    }

    @Override
    public T create(T t) {
        this.entityManager.persist(t);
        return t;
    }

    @Override
    public T read(PK id) {
        return this.entityManager.find(entityClass, id);
    }

    @Override
    public T update(T t) {
        return this.entityManager.merge(t);
    }

    @Override
    public void delete(T t) {
        t = this.entityManager.merge(t);
        this.entityManager.remove(t);
    }
}
86
Pascal Thivent

Sur la base de l'article Ne répétez pas le DAO nous avons utilisé ce type de technique pendant de nombreuses années. Nous avons toujours eu des problèmes avec nos modèles après avoir réalisé que nous avions fait une grosse erreur.

En utilisant un outil ORM tel que Hibernate ou JPA, vous n'aurez pas à penser la couche DAO et Service séparément. Vous pouvez utiliser EntityManager à partir de vos classes de service car vous connaissez le cycle de vie des transactions et la logique de vos classes d'entités.

Économisez-vous une minute si vous appelez myDao.saveEntity au lieu de simplement entityManager.saveEntity? Non. Vous aurez une classe dao inutile qui ne fait rien d'autre mais qui sera un wrapper autour d'EntityManager. N'ayez pas peur d'écrire des sélections dans vos classes de service à l'aide d'EntityManager (ou session en hibernation).

Une dernière remarque: vous devez définir les limites de votre couche de service et ne pas laisser les programmeurs retourner ou attendre les classes Entity. Les programmeurs de couches UI ou WS ne devraient pas du tout connaître les classes d'entités uniquement sur les DTO. Les objets d'entité ont des cycles de vie que la plupart des programmeurs ne connaissent pas. Vous rencontrerez de sérieux problèmes si vous stockez un objet entité dans les données d'une session et essayez de le mettre à jour dans la base de données quelques secondes ou heures plus tard. Eh bien, vous ne le feriez peut-être pas, mais un programmeur de l'interface utilisateur qui connaît uniquement les types de paramètres et les types de retour de votre couche de service ferait pour enregistrer certaines lignes de code.

14
Balazs Zsoldos

Je cherchais cette même chose. J'ai trouvé ce qui semble être exactement cela - le projet JPA Spring-Data fourni par SpringSource. Il s'agit d'un port de code de Hadès et a maintenant (début 2011) été avalé par Spring et mieux intégré. Il vous permet d'utiliser un seul dao (SimpleJpaRepository) avec une création statique, ou d'étendre la classe JpaRepository de base pour créer n'importe quel dao spécifique à un objet avec des méthodes CRUD + prêtes à l'emploi. Permet également les grails comme les requêtes simplement en utilisant des noms de paramètres comme nom de la méthode - dans l'interface (aucune implémentation requise!) Ie findByLastname(String lastName); semble très prometteur - faire partie des projets Spring lui assurera certainement un avenir aussi. J'ai commencé à implémenter cela dans mon prochain projet maintenant.

5
Danny C

si vous recherchez une implémentation tierce, vous pouvez vérifier http://www.altuure.com/projects/yagdao/ . c'est un framework DAO générique basé sur des notes qui prend en charge JPA et hibernate

2
altuure

Vous pouvez également consulter http://codeblock.engio.net/data-persistence-and-the-dao-pattern/

Le code associé peut être trouvé sur github https://github.com/bennidi/daoism

Il a une intégration avec Spring et des exemples de configuration pour Hibernate et EclipseLink

1
bennidi