12
votes

Comment utiliser l'entitémanager doit-il être utilisé dans une couche de service et une couche d'accès aux données bien découplées?

Un peu liée à mon autre question Si l'hiberne brut annoté de Pojo annoté est renvoyé de la couche d'accès aux données ou des interfaces à la place? , je suis expérimenté dans la création de couches joliment découplées, mais n'utilisez pas Hibernate ou J2EE / JPA. J'ai examiné la documentation et les tutoriels et je suis perplexe sur la façon d'utiliser l'entitémanger de manière élégante, car il semble que cela soit responsable des deux transactions (que je souhaite faire à ma couche de service) et des méthodes de persistance (que je veux rester dans la couche d'accès aux données). Devrais-je le créer à la couche de service et l'injecter dans la couche d'accès aux données ou y a-t-il une meilleure façon? Le pseudo-java ci-dessous montre à peu près ce que je pense faire.

EDIT: Mon pseudocode ci-dessous est essentiellement pris du didacticiel JPA hibernate et modifié pour la séparation des couches et ne reflète pas que le produit est en cours de développement. courir dans un conteneur EJB (de poisson de verre). Dans vos réponses, veuillez donner des meilleures pratiques et des exemples de code pour le code exécutant dans Glassfish ou équivalent. xxx


2 commentaires

Je vois que vous n'utilisez pas le JTA - est-ce exprès? Vous créez votre gestionnaire d'entité à la main et utilisez les transactions au niveau des ressources. Êtes-vous sur le serveur Tomcat ou Java Ee?


@Pedrokowalski J'ai essentiellement volé ce code du tutoriel Hibernate. L'application sera réellement dirigée dans Glassfish. Je vais éditer la question à demander de l'aide à ce sujet également :)


3 Réponses :


2
votes

Typiquement, vous voudriez isoler tout code de persistance à votre couche DAO. Donc, la couche de service ne doit même pas savoir entitymanager . Je pense que c'est bien si Dao Layer retourne des pojos annotés puisqu'ils restent des pojos toujours.

Pour la gestion des transactions, je vous suggère de regarder printemps orm . Mais si vous choisissez de ne pas utiliser Spring ou autre solution AOP, vous pouvez toujours exposer les méthodes liées à la transaction via votre DAO afin que vous les appeliez à partir de la couche de service. Cela fera votre vie beaucoup plus fort mais le choix est à vous ...


2 commentaires

L'entitémanager n'est-il pas déjà un DAO? Cela vous donne la belle interface crud et est la base de données-agnostique.


J'aimerais utiliser le printemps mais pas une option pour ce projet. Exposer la logique de transaction en tant que méthodes DAO semble tout simplement fausse - vous pourriez peut-être clarifier avec un exemple de code.



13
votes

Tout d'abord, si vous devriez utiliser une couche DAO ou non est un débat qui existe depuis l'apparition de JPA et l'entitémanager que de nombreuses personnes considèrent comme une DAO elle-même. La réponse à cela dépend du type d'application que vous développez, mais dans la plupart des cas, vous voudrez:

  • Utilisez des critères JPA ou des requêtes personnalisées strong>. Dans ce cas, vous ne voulez probablement pas mélanger votre logique commerciale avec votre création de requête. Cela conduirait à de grandes méthodes et enfreindrait le Principe de responsabilité unique . Li>
  • réutiliser votre code JPA autant que possible strong>. Dites que vous créez une requête de critère qui récupère une liste d'employés dont l'âge est compris entre 40 et 65 ans et travaille dans la société depuis plus de 10 ans. Vous voudrez peut-être réutiliser ce type de requête ailleurs dans votre couche de service, et si tel est le cas, l'avoir dans un service rendrait cette tâche difficile. Li> ul>

    qui étant dit, si tout ce que vous avez dans votre application est des opérations de crud et que vous ne pensez pas que vous devriez avoir besoin de réutiliser un code JPA, une couche DAO est probablement quelque chose de surenvochant car il agira comme un simple Wrapper de l'entitémanager, qui ne sonne pas correctement. P>

    Deuxièmement, je vous conseillerais d'utiliser des transactions gérées du conteneur chaque fois que possible. Si vous utilisez un conteneur EJB comme Tomee ou JBoss, cela éviterait une grande quantité de code dédié à créer et à gérer des transactions de manière programmatique. P>

    Dans le cas où vous utilisez en EJB conteneur, vous pouvez profiter de Gestion des transactions déclaratives. Un exemple de ceci utilisant DAOS serait de créer vos composants de la couche de service en tant que EJBS et vos DAO. P>

    @Stateless
    public class CustomerService {
    
        @EJB
        CustomerDao customerDao;
    
        public Long save(Customer customer) {
    
            // Business logic here
            return customerDao.save(customer);
        }
    }
    
    @Stateless
    public class CustomerDao {
    
        @PersistenceContext(unitName = "unit")
        EntityManager em;
    
        public Long save(Customer customer) {
            em.persist(customer);
            return customer.getId();
        }
    
        public Customer readCustomer(Long id) {
                // Criteria query built here
        }
    
    }
    


3 commentaires

Cela fonctionnera dans Glassfish, donc je modifierai la question pour être explicite à ce sujet. Votre code d'exemple suppose un conteneur EJB, oui?


Oui. Le code ci-dessus assume un conteneur conforme à la jee, quels sont les poissons de verre.


Je choisirais pour cette solution alors, alors gonzalo - vous avez ma hache ... Vote Je veux dire :-). Vous pouvez le modifier un peu pour fournir votre service avec des opérations de CRUD (c'est-à-dire créer GenericCrudservice). Ensuite, certains de vos services qui sont clairement basés à CRUD n'auront pas de DAO spécifique et si les services devraient réutiliser certaines requêtes compliquées, celles-ci peuvent être définies en classe séparée, comme le montre Gonzalo ou traité comme un référentiel DDD.



0
votes

Pour des cas simples tels que GetItem (), GetEnployee (), mieux injecter l'entitémanager directement à l'utilisation de la couche de service dans une méthode au lieu de la méthode de service appelant une DAO (qui a l'injection de gestionnaire d'entité injectée) renvoyer l'objet. Ceci est surkill et le DAO agit simplement comme un wrapper. Pour une logique commerciale complexe impliquant des requêtes et des critères, laissez la méthode de service appeler DAO qui parle TOT EH DB.


0 commentaires