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. Strong> p>
3 Réponses :
Typiquement, vous voudriez isoler tout code de persistance à votre couche DAO. Donc, la couche de service ne doit même pas savoir Pour la gestion des transactions, je vous suggère de regarder entitymanager code>. Je pense que c'est bien si Dao Layer retourne des pojos annotés puisqu'ils restent des pojos toujours. P>
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.
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:
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 } }
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.
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. p>
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 :)