IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JPA Java Discussion :

DAO pour JPA: les meilleures pratiques?


Sujet :

JPA Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Consultant informatique
    Inscrit en
    Octobre 2002
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Octobre 2002
    Messages : 89
    Par défaut DAO pour JPA: les meilleures pratiques?
    Bonjour
    Je suis à la recherche de “bonne pratique” pour implémenter des DAO avec JPA.
    (J’utilise Spring et Hibernate)
    Il y a bien des bonnes idées dans la doc de référence de spring, mais je trouve quand même l’API de JPA « pauvre »
    Je suis pour l’instant en test avec des DAO générique de google :
    http://code.google.com/p/generic-dao/
    L’API est vraiment mieux, c’est puissant, mais je trouve dommage que les entity doivent implémenter une interface spécifique.

    Quel sont vos bonne pratique ?

  2. #2
    Expert confirmé
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Par défaut
    Bonjour.
    Veux tu expliquer s'il te plaît ce que tu veux dire par API pauvre ? DAns son contexte (la persistance des données), je ne vois pas comment l'API de JPA est pauvre, excepté le manque de la recherche par Criteria, comme celle offerte par Hibernate par exemple, et ça, c'est prévue pour JPA 2.0.

    Sinon, de point de vue pratique, je n'utilise jamais les classes Templates ou Support de Spring: je préfère garder mes DAOs JPA indépendants de Spring qui se contente juste de leur injecter un EntityManager. Le reste (listing, ajout, màj et suppression), je le fais avec l'API nue de JPA.

    Autre chose: dans 99% des cas, mes DAOs JPA sont des coques vides: tout le boulot est réalisé par un DAO générique et abstrait concocté et développé par mes soins qui fait tout le sale boulot. En général, dans mes DAOs concret, soit je me contente d'hériter de ce DAO abstrait, soit j'y ajoute quelques recherches via des requêtes nommés et le tour est joué.
    Merci les génériques et l'API de reflection de Java

    Dans l'attente de plus d'explications, @+ !

  3. #3
    Membre expérimenté Avatar de a.snaps
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    209
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 209
    Par défaut
    Pareil pour moi: http://jroller.com/greenhorn/entry/uberdao_for_jpa
    Même si entre temps il s'est pas mal enrichi...
    Mais je suis toujours perplexe quant à l'utilité de DAO (que je préfère d'ailleur appeler Repository dans un contexte d'ORM). J'ai également une API qui vérifie si un persist ou merge est nécessaire. Mais le dernier retournant l'entitée managée cela ne facilite rien...
    De plus, comme j'utilise Hibernate, dès que j'ai besoin des "Filter"s je me retrouve à injecter le PersistenceContext dans mes Façades. Ou dès que je dois intéragir avec le cache (L1 ou L2), je l'injecte dans mes Services...
    Mais pour ce qui est "fetch plan" la couche prend tout son sens!
    Suis toujours mitigé
    Alex

  4. #4
    Expert confirmé
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Par défaut
    Bonjour.
    @Alexander: J'ai vu l'exemple dans ton blog et c'est exactement ça ! enfin presque, y'a bien sur quelques ptites differences mais le principe est là !
    Ah, jolie la vérification du nom de la table via reflection + annotation Entity ! Moi, j'utilisais bêtement le nom de la classe :-).

    Citation Envoyé par a.snaps Voir le message
    Mais je suis toujours perplexe quant à l'utilité de DAO (que je préfère d'ailleur appeler Repository dans un contexte d'ORM).
    Euh ... Comment veux tu communiquer avec ta DB autrement ?

    Citation Envoyé par a.snaps Voir le message
    J'ai également une API qui vérifie si un persist ou merge est nécessaire. Mais le dernier retournant l'entitée managée cela ne facilite rien...
    Ha ! Je connais trop bien ça ! J'en ai vu des vertes et des pas mures ! La solution est Spring + Extended Entity Manager.

    Citation Envoyé par a.snaps Voir le message
    De plus, comme j'utilise Hibernate, dès que j'ai besoin des "Filter"s je me retrouve à injecter le PersistenceContext dans mes Façades.
    Là je comprends plus rien ... J'ai moi même eu besoin de l'API Criteria d'Hibernate dans un contexte JPA et je l'ai implémenté dans le DAO (logique, non ? bon, mais môche quand même ...)


    Citation Envoyé par a.snaps Voir le message
    Ou dès que je dois intéragir avec le cache (L1 ou L2), je l'injecte dans mes Services...
    Tu as d'autres applications qui écrivent dans ta DB ?

    Citation Envoyé par a.snaps Voir le message
    Mais pour ce qui est "fetch plan" la couche prend tout son sens!
    huh ? tu parles du fetch mode (lazy/eager) ?


    Citation Envoyé par a.snaps Voir le message
    Suis toujours mitigé
    Ah oui !

    @+

  5. #5
    Membre expérimenté Avatar de a.snaps
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    209
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 209
    Par défaut
    Citation Envoyé par djo.mos Voir le message
    Bonjour.
    @Alexander: J'ai vu l'exemple dans ton blog et c'est exactement ça ! enfin presque, y'a bien sur quelques ptites differences mais le principe est là !
    Ah, jolie la vérification du nom de la table via reflection + annotation Entity ! Moi, j'utilisais bêtement le nom de la classe :-).


    Euh ... Comment veux tu communiquer avec ta DB autrement ?
    En utilisant l'entitymanager directement et des namedquery'es
    Citation Envoyé par djo.mos Voir le message

    Ha ! Je connais trop bien ça ! J'en ai vu des vertes et des pas mures ! La solution est Spring + Extended Entity Manager.
    Vais y jeter un oeil...
    Citation Envoyé par djo.mos Voir le message

    Là je comprends plus rien ... J'ai moi même eu besoin de l'API Criteria d'Hibernate dans un contexte JPA et je l'ai implémenté dans le DAO (logique, non ? bon, mais môche quand même ...)
    Je parle des filters: http://www.hibernate.org/hib_docs/re...l/filters.html
    Citation Envoyé par djo.mos Voir le message

    Tu as d'autres applications qui écrivent dans ta DB ?
    Oui, mais ce n'est pas pour ça. Plus pour la gestion de mémoire et autre lors de batch....
    Citation Envoyé par djo.mos Voir le message

    huh ? tu parles du fetch mode (lazy/eager) ?
    Oui, mais des méthodes genres:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CommandeDAO.getCommandeParId(Long): Commande
    CommandeDAO.getCommandeEtLigneParId(Long): Commande
    Ou la seconde prends les lignes de commande associées en une seule query DB

    Citation Envoyé par djo.mos Voir le message

    Ah oui !

    @+

  6. #6
    ndp
    ndp est déconnecté
    Membre expérimenté Avatar de ndp
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    227
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 227
    Par défaut
    une petite discussion interessante a lire:

    http://www.fabiokung.com/2007/11/12/...-repositories/

    C'est sur le concepte de Repository/DAO. Je suis tombe dessus, quand je cherchais egalement des infos sur JPA/Dao/Repository.

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 74
    Par défaut
    Grand débat...

    Peut etre qu'il faut admettre finallement que la couche DAO existe mais elle est générique (complètement): la classe proncipale de votre DAO s'appelle l'entityManager qui couvre tous vos besoins: lecture, sauvegarde, modificaiton (dirty checking), suppression, et recherche.

    L'usage de l'entity manager dans la couche service (ou métier si vous préférez), ne me gène pas ou en tout cas pas plus que l'usage d'une méthode ProductDAO.getProduct(id); d'autant plus qu'il s'agit bien d'une norme, contrairement à l'objet session d'hibernate qui fait exactement la meme chose mais induisait une dépendance vers un framework non normalisé.

    la question est donc de savoir s'il est préférable d'ecrire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public List<Client> rechercheClientParVille(String ville) {
      return ClientDAO.listeClientParVille(ville);
    }
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    public List<Client> rechercheClientParVille(String ville) {
      return entityManager.createQuery("From Client c where c.ville=:ville").setParamater("ville",ville).list()

    pour moi, la deuxième solution est vraiment envisageable d'autant qu'ejbql est un langage de requetage objet indépendant du mondèle de stockage

    Voila mon avis :-)
    Mais c'est un sujet polémique !
    Le DAO ne disparait pas, JPA vous en fournie un totalement générique ! pourquoi ne pas l'utiliser.



    Citation Envoyé par cisco Voir le message
    Bonjour
    Je suis à la recherche de “bonne pratique” pour implémenter des DAO avec JPA.
    (J’utilise Spring et Hibernate)
    Il y a bien des bonnes idées dans la doc de référence de spring, mais je trouve quand même l’API de JPA « pauvre »
    Je suis pour l’instant en test avec des DAO générique de google :
    http://code.google.com/p/generic-dao/
    L’API est vraiment mieux, c’est puissant, mais je trouve dommage que les entity doivent implémenter une interface spécifique.

    Quel sont vos bonne pratique ?

  8. #8
    Expert confirmé
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Par défaut
    Bonjour.
    En y allant à ta façon, c'est vrai su'on utilise JPA-QL qui est Objet et indépendant de la base de données. Toutefois, tu lies ta couche Services irrémediablement à un API de persistance spécifique (JPA) et tu ne pourras pas les réutiliser dans un autre projet avec JDBC/Spring JDBC/Toplink/Hibernate/JDO/etc. comme couche de persistance d'où la nécessité de l'abstraction offerte par la couche DAO.

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 74
    Par défaut
    Citation Envoyé par djo.mos Voir le message
    Bonjour.
    tu ne pourras pas les réutiliser dans un autre projet avec JDBC/Spring JDBC/Toplink/Hibernate/JDO/etc. comme couche de persistance d'où la nécessité de l'abstraction offerte par la couche DAO.
    oui, c'est juste. Si vous avez besoin de porter vos applications en utilisant d'autres technos, alors le dao est nécessaire mais il va se résumer à Peau de chagrin... reste simplement pour vous à savoir si cela correspond à votre besoin... A force de mettre des couches des indirections etout etout dans tous les sens on perd complètement les développeurs :-) mais ce que dis djo.mos est très juste.

  10. #10
    ndp
    ndp est déconnecté
    Membre expérimenté Avatar de ndp
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    227
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 227
    Par défaut
    Sur mon projet actuel, on pourrait concretement supprimer cette couche DAO. Ca part du constat que dans notre cas, il n'y a pas de changement du support de persistence, la seule grande revolution de ce cote la, ca a ete une montee de version du sgbd.

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 74
    Par défaut
    Sans remettre en cause le bien fondé du sempiternel découpage Presentation/Service/dao (avec les variantes qu'il comporte), il ne faut pas non plus tomber dans l'excès qui est souvent a l'origine de complexité resultant sur l'effet inverse souhaité: projet inmaintenable car architecture pas assez pragmatique (en partant du principe qu'il est livré dans les délais).

    Un argument supplementaire à ne pas systématiquement utiliser de DAO spécifique (et donc utiliser l'entity manager directement dans la couche service): Une utilisation simplifié des transaction au niveau de la couche de service (car c'est leur place), plutot que dans la couche de DAO: on peut alors presque mettre Spring à la poubelle (pour la gestion des transactions tout du moins).

    Il faut bien être conscient que peu de développeur Java ont suffisament de recul pour utiliser à bon escient struts ou jsf, ou meme jsp et servlet directement avec spring+jpa ou hibernate convanblement.... Les audits que j'ai eu l'occasion de faire sur ce type de projet étaient souvent catastrophique...

    D'ailleurs pour ceux qui font du spring + Jpa, je ne peux que vous inviter à regarder la spec ejb3 dans son intégralité: la démarcation des transactions est le job des ejb session et la version 3 de ces composants est au moins aussi simple (voire plus) que ce que propose spring pour répondre au même problème !

    mon rêve: après la "fusion" entre ejb entité et hibernate, une fusion "ejb session"/Spring




    Citation Envoyé par ndp Voir le message
    Sur mon projet actuel, on pourrait concretement supprimer cette couche DAO. Ca part du constat que dans notre cas, il n'y a pas de changement du support de persistence, la seule grande revolution de ce cote la, ca a ete une montee de version du sgbd.

  12. #12
    Rédacteur
    Avatar de benwit
    Profil pro
    dev
    Inscrit en
    Septembre 2004
    Messages
    1 676
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Septembre 2004
    Messages : 1 676
    Par défaut
    Citation Envoyé par djo.mos Voir le message
    Bonjour.
    En y allant à ta façon, c'est vrai su'on utilise JPA-QL qui est Objet et indépendant de la base de données. Toutefois, tu lies ta couche Services irrémediablement à un API de persistance spécifique (JPA) et tu ne pourras pas les réutiliser dans un autre projet avec JDBC/Spring JDBC/Toplink/Hibernate/JDO/etc. comme couche de persistance d'où la nécessité de l'abstraction offerte par la couche DAO.
    Un truc doit m'échapper ...

    Dans le cas où on utilise une couche de DAO, certes, on pourra réutiliser la couche Service. Mais pour utiliser une autre API de persistence (JDO, ...), il faudra disposer également d'une implémentation des DAO pour cette autre API, n'est ce pas ?

    Or, dans l'exemple proposé par Denis où l'on se passe des DAO, n'est t'il pas plus simple de constater qu'il suffit de faire une autre implémentation du service pour la nouvelle API ?

    1° CAS (avec DAO) :

    Extrait de "ServiceImpl extends Service":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public List<Client> rechercheClientParVille(String ville) {
      return ClientDAO.listeClientParVille(ville);
    }
    Le service est certes indépendant de l'implémentation de la persistance mais il faut bien une implémentation de ClientDAO pour JPA, JDO, ... ?
    Et ceci, pour chaque DAO !


    2° CAS (sans DAO) :

    Extrait de "JPAService implements Service" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    public List<Client> rechercheClientParVille(String ville) {
      return entityManager.createQuery("From Client c where c.ville=:ville").setParamater("ville",ville).list()
    Il ne faut plus que fournir une autre implémentation du Service (JDOService) ?

    Et s'il y a du code commun à JDOService et JPAService, il suffit qu'il étendent un AbstractService ...

Discussions similaires

  1. Réponses: 61
    Dernier message: 29/12/2016, 13h58
  2. Quelles sont les meilleures pratiques pour une démonstration en ligne?
    Par bbalet dans le forum Langages de programmation
    Réponses: 1
    Dernier message: 25/02/2015, 15h07
  3. Réponses: 5
    Dernier message: 25/05/2009, 15h59
  4. génération de dao pour jpa
    Par sheik dans le forum JPA
    Réponses: 2
    Dernier message: 20/12/2007, 15h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo