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

时间:2009-11-02 15:55:50

标签: java hibernate hibernate-mapping

我有一张优惠券 - POJO映射到两张桌子。第一个映射分配实体名称“voucherA”并将POJO映射到TableA。第二个映射使用“voucherB”作为实体名称,并将POJO映射到TableB。

现在我还有一个映射到TableC的客户POJO。此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>

如何正确映射从客户到凭证的多对多关联列表,以便在持久存储客户POJO时,如果不存在TableA,凭证实体将持久存储到TableB?可以这样做吗?如果没有,那么解决方法会是什么样的,以便客户使用的优惠券持久保存到tableB? (TableA仅包含可用的凭证,而不是已使用的凭证)

2 个答案:

答案 0 :(得分:3)

您的核心模型似乎有误。你的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表中进行物理删除(除非从未使用过有问题的凭证)。你必须改为逻辑删除。

答案 1 :(得分:1)

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

即使你有现有的数据,看起来似乎也不会非常困难。一旦所有优惠券都在同一张桌子上,他们与顾客的关系就会变成一个直截了当的多对多。

我认为保持两张桌子会很困难。从本质上讲,您仍在存储是否使用凭证,但您没有明确地使用凭证。我确信可以有一个解决方法,但我认为我上面概述的内容要简单得多。根据我的经验,这是我每次遇到类似问题时选择的路线。