web-dev-qa-db-fra.com

Java EE Architecture - Les DAO sont-ils toujours recommandés lors de l'utilisation d'un ORM comme JPA 2?

Si j'utilise un ORM comme JPA2 - où j'ai mes entités qui sont mappées à ma base de données, dois-je quand même utiliser un DAO? Cela semble être beaucoup plus de frais généraux.

Par exemple, je devrais conserver trois packages supplémentaires:

  1. Celui qui spécifie mes objets de domaine (qui mappent à peu près mes objets Entity):

    public class Employee {
        private String firstName;
        private String lastName;
        ...
        // Getters and setters
    }
    
  2. Celui qui contient des interfaces qui spécifient mes méthodes DAO

    public interface EmployeeDAO {
        public void addEmployee(Employee employee);
        public Employee getEmployeeById(long id);
        ...
    }
    
  3. Celui qui contient des beans de session qui implémentent mes DAO

    public EmployeeJpaDAO implements EmployeeDAO {
        interface method implementations here
        ....
        private method that transform my Employee entity into my Employee domain object
    }
    

Maintenant, c'est beaucoup de bagages supplémentaires à ajouter chaque fois que j'ai besoin d'effectuer une nouvelle opération CRUD.

Cependant, les avantages que je vois d'avoir un DAO sont:

  1. Vous pouvez avoir une implémentation en mémoire du DAO pour tester l'unité de votre couche de service. Cela signifie que vous n'avez pas besoin d'accéder à la base de données pour tester la logique métier, et vous pouvez être assuré que vos objets contiendront toujours les mêmes valeurs pour les propriétés

  2. Il sépare la logique métier de la logique d'accès à la base de données

L'option qui n'implique pas la mise en œuvre d'un DAO consiste à simplement utiliser des objets d'entité et EntityManager dans la couche de service:

@Stateless
public class EmployeeEjb {
    @PersistenceContext(unitName = "employee")
    private EntityManager manager;

    public Employee getEmployeeById(long id) {
        return manager.createNamedQuery(Employee.GetEmployeeById).getResultList();
    }
    ...
}

N'y a-t-il pas de terrain d'entente ici? Quelqu'un a-t-il rencontré une architecture ou mis en œuvre une architecture qui répond à certains des avantages d'une couche DAO (surtout la testabilité unitaire de la logique métier) que j'ai mentionnée ci-dessus, mais n'implique pas tous les frais généraux impliqués pour implémenter une couche DAO?

Merci pour toutes recommandations et/ou suggestions! Je suis vraiment curieux de voir ce que certaines personnes ont proposé à ce sujet.

46
Brian DiCasa

Si j'utilise un ORM comme JPA2 - où j'ai mes entités qui sont mappées à ma base de données, dois-je quand même utiliser un DAO? Cela semble être beaucoup plus de frais généraux.

C'est. Et clairement, Java EE n'encourage pas l'utilisation du modèle DAO lors de l'utilisation de JPA (JPA fournit déjà une implémentation standardisée de le modèle Domain Store et il n'y a pas beaucoup de valeur à le protéger derrière un DAO.) Je trouve que le DAO est anti - SEC dans une telle situation.

Donc, pour les cas simples (en fait, la plupart des cas), je saute avec plaisir le DAO et je n'ai aucun problème avec cela. Pour des cas plus complexes (par exemple lors de l'utilisation de procédures stockées, de fichiers plats), je l'utilise. En d'autres termes, cela dépend, comme résumé dans JPA a-t-il tué le DAO? . Voir également les questions connexes ci-dessous:

Questions connexes

(...) Celui qui contient des beans session qui implémentent mes DAO

Non, vous ne voulez certainement pas implémenter un DAO en tant que bean session:

  • Vous ne voulez pas créer autant de beans session (regroupés) que de tables (gros gaspillage de ressources)
  • Vous ne voulez pas enchaîner les Session Beans partout, ne reproduisez pas les erreurs du passé, c'est une mauvaise pratique connue qui ne s'adapte pas bien.

Donc, si vous voulez vraiment suivre la voie DAO et que l'EM soit injecté, implémentez vos DAO en tant que beans Spring (dans Java EE 5) ou bean géré CDI (dans Java EE 6).

Vous pouvez avoir une implémentation en mémoire du DAO pour tester l'unité de votre couche de service.

Si vous voulez vraiment faire des tests unitaires , moquer le DAO/EntityManager, il n'y a pas de différence. Et si vous souhaitez effectuer des tests d'intégration, vous pouvez configurer JPA pour utiliser une base de données en mémoire. Donc à la fin, je n'achète tout simplement pas cet argument.

Il sépare la logique métier de la logique d'accès à la base de données

Honnêtement, je ne vois pas de grande différence entre compter sur un DAO contre un gestionnaire d'entité, je ne vois pas comment un DAO sépare les choses "mieux ". Encore une fois, je n'achète pas cet argument.

Et d'après mon expérience, le changement de la solution de persistance sous-jacente est un événement très exceptionnel et je ne vais pas introduire de DAO pour quelque chose qui ne se produira probablement pas ( YAGNI , BAISER ).

N'y a-t-il pas de terrain d'entente ici? Quelqu'un a-t-il rencontré une architecture ou mis en œuvre une architecture qui répond à certains des avantages d'une couche DAO (surtout la testabilité unitaire de la logique métier) que j'ai mentionnée ci-dessus, mais n'implique pas tous les frais généraux impliqués pour implémenter une couche DAO?

Je ne vois pas beaucoup de compromis et, comme le laisse fortement entendre, je n'utilise pas de DAO si je n'en ressens pas le besoin. Et comme je l'ai dit, moquez le EntityManager si vous voulez vraiment tester unitairement la logique métier. Cela fonctionne pour moi et je suis heureux d'écrire moins de code.

Plus de ressources

48
Pascal Thivent

Pour mémoire.

Pour le principe de responsabilité unique (SRP), DAO est un must have, il sépare le modèle et la logique dans une couche de persistance qui peut être facilement portable.

Si un projet utilise Test Unit, DAO aide à le tester correctement (maquette, test de base de données, etc.).

DAO est un SERVICE et, comme un, nous pourrions envelopper notre processus dans une classe joliment facile à entretenir.

JPA réduit le nombre de lignes de codes mais, rien de plus, les anciennes règles s'appliquent toujours.

JPA apporte une couche de référentiel mais son pas NOTRE couche de référentiel. Dans le même principe, disons que nous avons encapsulé une logique qui obtient le profit d'un processus. Peut-être que l'encapsulation est simplement une multiplication pour 0,1 mais elle est toujours digne d'être encapsulée.

Par exemple, disons que j'ai le problème suivant: pour une raison étrange, je peux insérer un nouveau client dans la base de données ?. Où dois-je commencer à tester?. a: ClientDao s'il existe, sinon, bonne chance à trouver ailleurs.

4
magallanes