2009-11-30 12 views
12

J'ai une application d'entreprise Java qui fournit un service Web, une couche de domaine et une couche de persistance d'hibernation. Dans ce cas particulier, il n'y a pas de grande différence (pour l'instant) entre les objets que j'envoie sur le réseau, les objets de domaine et les objets de persistance.Les classes de domaine reçoivent-elles généralement des annotations JPA ou JAXB ou les deux?

Actuellement, l'application utilise des DTO du côté de la persistance et annote les classes de domaine avec des annotations JAXB. Cependant, plus je lis et j'y pense, plus cela semble en arrière! (Sans compter qu'il y a beaucoup de code pour soutenir les va-et-vient entre les objets DTO et Domain). Il semble que la plupart des architectes suggèrent de mettre des annotations JPA sur le modèle de domaine et de créer des DTO pour envoyer des objets.

Dans mon cas, pourrais-je mettre les annotations JAXB et JPA (Hibernate) sur mes classes de domaine? L'idée de garder ma façade de service Web, mon domaine et ma persistance étroitement liés semble facile à maintenir, mais cela me préoccupe, car ils peuvent avoir besoin de changer dans le temps. Mais serait-il plus intelligent de créer un ensemble de classes DTO pour les services Web et d'ignorer les DTO pour la persistance?

Répondre

11

Il n'y a pas de raison fonctionnelle pour ne pas annoter la même classe avec les annotations JPA et JAXB, je l'ai fait moi-même à l'occasion. Cependant, cela devient un peu difficile à lire, et parfois vous voulez des compromis différents de conception de classe avec JAXB et JPA. Dans mon expérience, ces compromis signifient généralement que vous vous retrouvez avec deux modèles de classe.

+2

Il est logique que tôt ou tard, vous aurez besoin de les séparer en couches. Mais dans un tout nouveau projet, cela permet de gagner beaucoup de temps pour les combiner. Bon à savoir, il n'y a pas de mauvais effets secondaires de faire cela. – HDave

+10

Et là encore je les referme 2 ans plus tard car notre client webapp ne veut consommer que les données dont il a besoin, donc nous faisons des DTO (avec des annotations JAX-B) qui sont séparées de nos entités de domaine (JPA). – HDave

2

Il n'y a aucun problème à utiliser les deux annotations sur la même classe. J'ai même tendance à encourager cela, parce que vous n'avez donc pas à copier-coller lorsque des changements se produisent. Dans certains cas, certaines propriétés ont un comportement différent. Par exemple, un ID généré automatiquement peut ne pas être requis pour être appelé. @XmlTransient et @Transient sont ensuite combinés. Cela devient un peu difficile à lire, mais pas trop dur, car il est évident que toutes les annotations signifient.

5

Je suis d'accord que l'utilisation des mêmes classes de modèles est la bonne approche.Si vous êtes préoccupé par l'encombrement d'annotation, vous pouvez utiliser une implémentation JAXB (comme EclipseLink JAXB) qui fournit un mécanisme pour externalisant les métadonnées:

En outre, depuis que vous utilisez un modèle JPA EclipseLink JAXB (Moxy) a des extensions pour faciliter cette tâche:

Voici un exemple d'utilisation d'un modèle avec JAXB & JPA pour créer un service RESTful:

1

Toute personne tentée de mettre des objets de lien atom dans votre domaine persistant parce que vous vous êtes engagé à définir votre structure XML de service Web là-bas? Cela me semble étrange de le faire. Les liens Hateoas semblent être une bonne idée mais le domaine persistant et le service impl (pas le service web) n'ont aucun intérêt dans les liens atomiques. Là encore, en utilisant des annotations xml et en jersey sérialiser mon domaine pour moi est certainement pratique. Un autre inconvénient de cette approche est qu'il est facile d'influer sur les consommateurs de votre service Web à l'exécution avec le refactoring "couche" de domaine de persistance.

+0

Je suis d'accord que le lien Atom (et leurs annotations JAX-B) n'appartient pas à un module de domaine. Cependant, il peut toujours être judicieux de mettre des annotations JAX-B sur les classes de domaine que vous avez là. Cela dit, j'utilise aussi des fichiers de mapping XML JAX-B via MOXy que je trouve extrêmement pratique, en plus on peut fournir des mappages différents pour différents endpoints. – HDave

1

Je sais que cette question est un peu ancienne, mais je pensais que je peserais de toute façon puisque c'est un problème que j'ai récemment rencontré. Ma recommandation serait de laisser vos classes annotées JAXB seules, puisque tout changement de schéma nécessitera de générer de nouveau ces classes. Cela signifie que vous devrez saisir de nouveau toutes les annotations d'hibernation, etc. manuellement. Cela peut être une solution obsolète, mais je pense qu'il serait parfaitement raisonnable de créer un fichier de mise en correspondance hibernate (.hbm.xml) pour héberger les mappages en externe. C'est un peu plus flexible, moins encombré, et tout aussi utile à mon avis.

+0

"Cela signifie que vous devrez saisir de nouveau les annotations d'hibernation, etc. manuellement". - Voir Hyperjaxb3, ce plugin crée des annotations JPA atumatiquement. http://confluence.highsource.org/display/HJ3/Home Disclaimer: Je suis l'auteur. – lexicore

+0

Mes pensées, un an plus tard: les chances qu'une classe corresponde parfaitement aux annotations JPA et JAXB sont minces. Je recommanderais de les distribuer dans des fichiers distincts 99% du temps. –