J'ai déjà posé cette question sur le Hibernate's forum, mais j'ai pensé que je le demanderais aussi ici.Mapper des objets de valeur complexe dans Hibernate
Je suis en train de cartographier le modèle suivant, tout en préservant la sémantique de la valeur des objets de valeur et TranslatedText
Translation
:
Les deux valeurs comme des objets dépendants
Idéalement je mapper TranslatedText
en tant que <component>
au sein de Question
et Translation
en tant que <bag>
de <composite-element>
au sein de TranslatedText
.
Il aurait été simple à la carte si Question
faisait référence à un seul TranslatedText
, mais comme il fait référence à deux je besoin d'une sorte de discriminateur en fonction du nom de la propriété contenant la valeur (title
ou description
) afin de cartographier la Translation
avec une clé de composition composée de (question_id,property_name,language_code)
. Un problème avec cela est que le propertyName
ne fait pas partie du modèle et ne devrait pas, mais je n'ai pas trouvé un moyen de forcer Hibernate à insérer une valeur qui ne vient pas du modèle.
Par conséquent, j'ai essayé de changer le modèle et mettre en place des classes spécialisées Title
et Description
pour que j'aurais un type
là-dedans que je pouvais utiliser comme un discriminateur.
A la fin qui ne permet pas vraiment beaucoup:
<component name="title" class="TranslatedText">
<bag name="translations" table="Translation">
<key>
<!-- PROBLEM: Could not find a way to create a custom join expression on question.id and question.title.type in here. -->
</key>
<composite-element class="Translation">
<!-- PROBLEM: Could not found a way to make Hibernate insert title.type from here, without having this value on the Translation object. -->
<property name="languageCode" type="string" column="language_code"/>
<property name="text" type="string"/>
</composite-element>
</bag>
</component>
TranslatedText avec <many-to-one>
j'ai réussi à obtenir quelque chose à ce que je besoin par cartographie TranslatedText
comme une entité au sein Question
en utilisant un <many-to-one>
puis mappez Translation
sous la forme d'une collection de valeurs au sein de TranslatedText
, mais le problème principal m avec cette approche est qu'il n'y a pas de moyen facile de se débarrasser de l'orphelins TranslatedText
et Translation
. Je devrais soit faire ceci avec un déclencheur de DB ou un processus programmé.
Conclusion
À ce stade, je suis sous l'impression que Hibernate est pas assez souple pour cartographier le modèle initial avec la sémantique appropriée, mais nous espérons que je me trompe et il y a une façon de le faire.
Eh bien, 'TranslatedText' est utile car elle assure qu'une seule traduction par le code, donc je ne peux pas me débarrasser, à moins que j'appliquer la règle avec une contrainte de DB, mais le modèle ne serait pas aussi expressif. Je pourrais utiliser 'Set 'à la place s'il était en Java, mais nous ne pouvons pas le faire puisque le modèle est en réalité écrit en ColdFusion (oui ce langage horrible), pas en Java. –
plalx
Il est difficile de comprendre vos contraintes sans contexte, mais il est possible d'avoir une telle relation en faisant les trois classes comme '@ Entity' (chacune d'elles aura son propre' @ Id'). Est-ce que ça va pour toi? Si oui, je peux préparer une telle configuration. –
Eh bien, comme je l'ai dit, j'ai réussi à le faire déjà en mappant 'TranslatedText' en tant qu'entité. Cependant, je ne peux pas faire 'cascade-delete-orphan' dans ce cas puisque j'ai utilisé un' many-to-one'. Les objets de valeur sont simplement des valeurs immuables simples telles que 'Date' ou' Integer'. Les mapper en tant que composants d'hibernation permettrait de résoudre le problème des orphelins. Je suis vraiment surpris qu'un tel scénario commun soit si difficile à cartographier. – plalx