2009-11-02 7 views
2

J'ai un bon - POJO mappé à deux tables. Le premier mappage attribue un nom d'entité "voucherA" et mappe le POJO à TableA. Le second mappage utilise "voucherB" comme nom d'entité et mappe le POJO à TableB.Comment faire correspondre une association plusieurs-à-plusieurs à une classe mappée à deux tables différentes?

Maintenant, j'ai aussi un client POJO mappé à TableC. Ce POJO référence les bons dans une liste.

<list name="vouchers" table="TableC_vouchers"> 
    <key column="pid"/> 
    <list-index column="position" base="0"/> 

    <!-- how to do that right --> 
    <many-to-many column="voucher_id" entity-name="voucherB"/> 
</list> 

Comment mapper correctement une liste de plusieurs à plusieurs associations de clients à des bons de sorte que si un POJO client est conservé, les entités Voucher sont conservés à TableB s'ils n'y existent pas, à la place de TableA? Cela peut-il être fait? Si ce n'est pas le cas, à quoi ressemblerait une solution de contournement pour que les bons utilisés par les clients soient conservés dans tableB? (La TableA ne contient que les bons disponibles, et non ceux utilisés)

+0

Juste pour clarifier, êtes-vous coincé en utilisant une table pour chaque type de bon? Serait-il inacceptable de stocker les deux types de bons dans une seule table? – Lyudmil

+0

La deuxième table ne doit contenir que les bons qui ont été utilisés. Dans mon cas également, un bon peut être utilisé plusieurs fois par différents utilisateurs. Dans ma question, la TableA peut être ignorée en tant que «Bons encore disponibles à utiliser» et en tant que «Bons qui ont été utilisés». Il peut également arriver que les bons de la TableA soient supprimés. Je suis coincé comment créer l'association de plusieurs à plusieurs. – Chris

+0

Je vois. Serait-il inacceptable si vous avez stocké un drapeau dans la table pour chaque bon qui serait vrai si le bon est utilisé et faux sinon. Je pense que de cette façon, vous pouvez toujours supprimer ceux qui ne sont pas utilisés à volonté, mais vous pouvez avoir tous les bons dans la même table, ce qui rend trivial plusieurs-à-plusieurs. – Lyudmil

Répondre

3

Votre modèle de base semble faux. Votre entité Voucher a vraisemblablement beaucoup d'attributs - est-ce que TOUS changent après qu'il soit utilisé par un Customer? Je doute que. Et pourtant, vous les dupliquez dans vos tables A et B, ce qui signifie que votre schéma n'est pas normalisé.

Le bon «disponible» et le bon «utilisé» ne sont pas (ou ne devraient pas être) la même entité. Je suggérerais plutôt que vous créiez une nouvelle entité pour UsedVoucher qui relierait à la fois Voucher comme plusieurs à un et Customer comme plusieurs-à-un et ne contiendrait que les propriétés «modifiées» de Voucher (le cas échéant). Ainsi,

Voucher(id, other attributes) // doesn't change from what you have now 
Customer (id, other attributes) // doesn't change except for many-to-many; see below 
UsedVoucher(id, 
voucher, // what Voucher was used by that customer 
customer, // what Customer has used that voucher 
changed voucher attributes, // if any 
additional attributes // if needed, such as date/time when voucher was used 
) 

Votre "many-to-many" sur Customer deviendra "one-to-many" (collections de bons utilisés par ce client) Si vous avez besoin comme propriété maintenable; Sinon, il est facilement récupérable via une requête.

Vous ne pouvez pas supprimer physiquement du tableau Vouchers dans ce scénario (sauf si le bon en question n'a jamais été utilisé). Vous devrez effectuer une suppression logique à la place.

+0

Je suis d'accord avec votre réponse. Juste à part, il est parfois légitime de choisir d'avoir un schéma dénormalisé. Avec Hibernate, le design dans le code influence fortement le schéma. Votre problème pourrait être tel qu'il est plus facile de faire quelque chose si vous utilisez l'héritage de table par sous-classe. Faire ce choix signifie souvent que vous allez dupliquer des données. Je m'arrêterais donc pour dire que le modèle est "faux". – Lyudmil

+1

Lyudmil - il existe différents types de dénormalisation, certains plus acceptables que d'autres. Dans ce cas, cependant, d'après ma compréhension de ce que OP voulait (et il n'a pas été très clair, pour être juste), je conseillerais de ne pas tout regrouper dans un même tableau. Vous obtiendrez ensemble des coupons «de base» et ** multiples ** «réclamés», ce qui vous empêchera d'avoir des contraintes significatives en ce qui concerne les clés FK/d'entreprise. D'ailleurs, j'ai dit "** semble mauvais" :-) - encore une fois, basé sur ma compréhension. – ChssPly76

1

Ma suggestion serait de stocker tous les coupons dans la même table. Pour distinguer les uns des autres et ceux qui ne sont pas utilisés, vous pouvez avoir un drapeau booléen ou une valeur discriminante (si vous utilisez l'héritage dans votre code Java).

Même si vous avez des données existantes, il ne semble pas que la migration serait terriblement difficile. Une fois que tous les coupons sont dans la même table, leur relation avec les clients devient directe et directe. Je pense que le maintien de deux tables serait difficile. Essentiellement, vous stockez toujours si un bon est utilisé ou non, mais vous ne le faites pas explicitement. Je suis sûr qu'il pourrait y avoir une solution de contournement, mais je pense que ce que j'ai décrit ci-dessus est beaucoup plus simple. Selon mon expérience, c'est le chemin que j'ai choisi à chaque fois face à un problème similaire.

Questions connexes