如何将多对多关联映射到映射到两个不同表的类?

问题描述:

我有一张凭证 - POJO映射到两个表。第一个映射指定实体名称“voucherA”并将POJO映射到TableA。第二个映射使用“voucherB”作为实体名称并将POJO映射到TableB。如何将多对多关联映射到映射到两个不同表的类?

现在我也有一个客户POJO映射到TableC。此POJO参考列表中的凭证。

<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> 

如何正确映射许多-to-many关联的从客户凭证列表,这样,如果客户POJO持久保存,该券的实体被保存到表B,如果不存在,他们在那里,而不是的表A?这可以做到吗?如果不是,解决方法是什么样的,客户使用的代金券会持续到tableB? (表A只包含可用的优惠券,而不是使用的优惠券)

+0

只是为了澄清,你是否坚持使用每种优惠券的表?将两种类型的代金券存放在单一表格中是不可接受的? – Lyudmil 2009-11-02 16:09:50

+0

第二张表只包含已使用的凭证。同样在我的情况下,不同的用户可以多次使用一张优惠券。在我的问题中,TableA可以理解为“凭证仍然可用”和TableB“已使用的凭证”。它也可能发生TableA的代金券被删除。我坚持如何创建多对多的关联。 – Chris 2009-11-02 16:15:38

+0

我明白了。如果您在表格中为每个凭证存储了一个标志,如果使用凭证则为真,如果不是,则为假。我想这样你仍然可以随意删除未使用的,但是你可以在同一个表中使用所有凭证,这使得多对多的微不足道。 – Lyudmil 2009-11-02 16:20:00

你的核心模型看起来不对。您的Voucher实体可能具有许多属性 - 它们在被Customer使用后是否会发生变化?我不信。然而,你在你的A和B表中复制它们,这意味着你的模式没有被标准化。

“可用”优惠券和“已用”优惠券不是(或不应该是)同一个实体。相反,我会建议您为UsedVoucher创建一个新实体,该实体将多对一地链接到Voucher,并且多对一链接到Customer,并且只包含Voucher(如果有)的“已更改”属性。所以,

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 
) 

你的“多到多”的Customer将成为“一个一对多”如果你需要它作为维护属性(由该客户使用优惠券的集合);否则它很容易通过查询获取。

但是,在此场景下,您不能从Vouchers表中物理删除,但(除非从未使用过有关凭证)。您必须改为执行逻辑删除。

+0

我同意你的答案。就像旁人一样,选择具有非规范化模式有时是合理的。在Hibernate中,代码中的设计严重影响了模式。如果你使用table-per-subclass inheritance,你的问题可能会更容易做些事情。做出这样的选择通常意味着你将要复制数据。因此,我会停下来说这个模型是“错误的”。 – Lyudmil 2009-11-03 13:41:09

+1

柳德米尔 - 有不同种类的非规范化,有些比其他更容易接受。然而,在这种情况下,基于我对OP要求的理解(而且他不是很清楚,公平),我绝对建议不要将所有内容都捆绑在一张表中。您最终将获得“基本”凭证和**多个**“声明”凭证,导致无法获得任何有意义的FK /业务密钥约束。此外,我说“**似乎错了”:-) - 再次,根据我的理解。 – ChssPly76 2009-11-03 16:57:53

我的建议是将所有优惠券存储在同一张表中。要区分已使用的和未使用的,您可以使用布尔标志或区分值(如果您在Java代码中使用继承)。

即使你有现有的数据,它似乎并不像迁移会非常困难。一旦所有优惠券都在同一张桌子上,他们与客户的关系就变成了多对多的直截了当。

我认为维护两张表格会很困难。基本上,你仍然在存储是否使用优惠券,但你没有明确地做。我相信可能有一种解决方法,但我认为我上面概述的更简单。根据我的经验,这是我每次遇到类似问题时所选择的路线。