Java, traitant des classes annotées XML et JPA
J'utilise xjc pour compiler des fichiers XSD en classes Java, et je souhaite les éditer / les étendre pour les rendre persistants via JPA.
Je ne peux pas comprendre quel est le meilleur "Couplage?" serait et comment l'organiser, si je modifie les classes compilées xjc pour qu'elles soient persistantes, je perdrais la possibilité de recompiler le XSD s'il y a des changements.
Même si je n'avais pas besoin de recompiler, dans certains cas, je ne pourrais toujours pas sérialiser / désérialiser les données collectées avant que mon schéma ne change.
Je ne veux pas complètement "découpler", car je veux garder la possibilité de persister l'objet XML importé avec juste quelques lignes de code (sans avoir à écrire une sorte de "convertisseur" pour chaque entité XML).
Quelqu'un at-il été confronté au même problème? Comment avez-vous réussi à le résoudre.
Réponses
Je pense que le plus gros problème auquel vous êtes confronté ici est que pour les classes qui doivent être "visibles" par quelque chose en dehors de votre code, il est important d'avoir une source de vérité pour ce qui compte comme des données valides. Sinon, vous vous retrouverez avec des heures de travail interminables consacrées à la synchronisation des nombreuses définitions et de leurs implémentations. Soit les spécifications sont désynchronisées (ou deviennent désynchronisées au fil du temps), soit les convertisseurs sont incompatibles avec les dernières versions des spécifications, etc. Dans votre cas, les classes sont toutes deux visibles pour
- tout ce qui produit / consomme les données XML qui sont converties vers / à partir des classes Java
- et à la base de données derrière JPA qui impose ses propres exigences de type et d'intégrité des données sur vos données.
Votre approche risque de violer ce principe important si vous n'y faites pas attention. Soit le XSD est la source de la vérité ou les JPA-définitions sont ou tout autre chose est, mais selon ce n-1 principe de n définitions ont à dépendre de la n-ième.
Donc, quelle est la solution? Comme toujours, cela dépend fortement de ce que vous voulez faire.
Peut-être qu'il n'y a pas beaucoup de classes et peut-être qu'elles ne changent jamais ou ne changent que très peu et très rarement. Dans ce cas, vous pouvez décider d'accepter le coût d'avoir deux sources de vérité.
Comment feriez-vous cela? Comme vous l'avez déjà dit, il est très fragile de modifier du code généré automatiquement. Il est également inutile d'avoir des (sous) classes séparées uniquement pour les annotations JPA, car cela nécessiterait beaucoup de code passe-partout pour les convertisseurs. Heureusement, la spécification JPA permet la configuration XML des mappages ORM au lieu de la configuration habituelle basée sur les annotations. Jetez un œil au fichier orm.xml . Avec lui, vous pouvez définir une classe comme une entité JPA sans aucune modification de son code source.
Si votre XSD est assez simple, il peut être possible de générer la structure de la base de données directement à partir du XSD. Il existe des outils pour cela. Cela ne vous donne cependant pas le mappage ORM. Mais si le XSD est assez simple, il peut également être possible de générer automatiquement le fichier orm.xml à partir du XSD. Cela rétablirait le XSD en tant que source unique de vérité.
Si 1. et 2. ne sont pas des options pour vous, parce que votre structure de données est trop compliquée, il est peut-être possible d'avoir une troisième spécification qui peut servir de source de vérité pour les deux et qui est capable de générer à la fois les XSD et les Définitions JPA sous une forme ou une autre. En principe, vous pouvez avoir un fichier XML augmenté contenant à la fois les définitions XSD et ORM, ainsi qu'un XSLT qui extrait les deux moitiés. (Bien sûr, vous pouvez utiliser n'importe quel autre (méta) langage au lieu de XML pour la spécification principale si vous le souhaitez) Ensuite, votre processus de compilation nécessiterait une autre étape avant. Mais attention: en fonction des complications de votre structure de données, cela peut être difficile à déboguer / modifier si le besoin s'en fait sentir.
Vous pourriez avoir le code Java comme source de vérité et exporter le XSD à la place. Bien sûr, vous pouvez utiliser l'exportation JSON au lieu de XML beaucoup plus facilement. Je ne pense pas que ce soit très probable, car les XSD sont généralement fournis à partir de spécifications externes et ne sont pas générés sur un coup de tête, mais bon, peut-être êtes-vous l'exception à la règle?
Dans tous les cas, vous devez être conscient que les subtilités des XML et des ORM comme JPA ne sont pas nécessairement compatibles les unes avec les autres et que votre désir d'unification complète peut être voué à l'échec dès le départ. Il se peut simplement que certains aspects de vos données XML ne puissent pas être convertis en base de données et vice versa. Par exemple: Un concept de transactions n'existe pas dans XML land. JPA a une connaissance (limitée) des procédures stockées, des déclencheurs de bases de données et d'autres fonctionnalités (semi) avancées des bases de données. Je ne suis pas au courant de quoi que ce soit dans XML land qui soit un peu similaire à cela. Et inversement, il n'y a pas de cousin proche de XSLT dans la base de données.
En plus de cela: JPA peut être très inefficace si vous gérez de grandes quantités de données; il écrit parfois du SQL horrible si votre configuration n'est pas optimisée; il a un comportement pas tout à fait simple avec les transactions, le chargement paresseux, etc. C'est génial pour extraire les détails des bases de données, mais comme avec une telle abstraction, cela peut vous coûter si vous ne savez pas ce que vous êtes Faire. Il peut être tout simplement impossible de corriger tous les points les plus fins lorsque vous laissez tout cela à un outil automatisé.
Vous devez garder cela à l'esprit afin de pouvoir fournir de bonnes interfaces à la fois pour ajouter des fonctionnalités manquantes à chaque extrémité et pour affiner les mappages.