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

Java 如何将多对多关联映射到映射到两个不同表的类?,java,hibernate,hibernate-mapping,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

我有一个凭证-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被持久化,凭证实体将被持久化到TableB(如果它们不存在),而不是TableA?这能做到吗?如果不是,解决方案会是什么样子,以便将客户使用的凭证持久化到tableB?(表A只包含可用的凭证,而不包含使用过的凭证)

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

即使您拥有现有数据,迁移似乎也不会非常困难。一旦所有凭单都在同一张表中,它们与客户的关系就变成了直接的多对多关系


我认为维护两张桌子会很困难。本质上,您仍然在存储凭证是否已使用,但您并没有显式地进行存储。我肯定会有解决办法,但我认为我上面概述的要简单得多。根据我的经验,每当遇到类似问题时,我都会选择这条路线。

您的核心模型似乎是错误的。您的
凭证
实体可能有许多属性-它们在
客户使用后是否都会发生变化?我对此表示怀疑。然而,您在A和B表中复制它们,这意味着您的模式没有规范化

“可用”凭证和“已使用”凭证不是(或不应该是)同一实体。我建议您为
UsedVoucher
创建一个新实体,该实体将链接到
凭证
多对一和
客户
多对一,并且只包含
凭证
的“更改”属性(如果有)。所以

如果您需要将
客户
上的“多对多”设置为“一对多”(此客户使用的凭证集合),作为可维护的财产;否则,可以通过查询轻松检索


不过,在这种情况下,您不能从
凭单
表中实际删除凭单(除非从未使用过有问题的凭单)。您必须执行逻辑删除操作。

只是想澄清一下,您是否一直在为每种凭证使用一个表?将这两种类型的凭证存储在一个表中是否不可接受?第二个表仅包含已使用的凭证。同样在我的例子中,一张凭证可以被不同的用户多次使用。在我的问题中,可以将表A取消为“仍可使用的凭单”和表B“已使用的凭单”。表A中的凭证也可能被删除。我被困在如何创建多对多关联中。我明白了。如果您在表中为每张凭证存储了一个标志,则该标志在使用凭证时为真,否则为假,这是否是不可接受的。我认为这样你仍然可以随意删除未使用的凭证,但你可以将所有凭证放在同一张表中,这使得多对多变得很琐碎。我更喜欢两张表的解决方案,但如果这不可能或太复杂而无法实现,我会选择一张表的解决方案谢谢你的澄清。我认为这是最简单的路线。你可以在下面找到我的“官方”答案。我同意你的答案。顺便说一句,选择非规范化模式有时是合理的。使用Hibernate时,代码中的设计会严重影响模式。您的问题可能是这样的,如果您使用每个子类的表继承,那么做起来会更容易。做出这样的选择通常意味着您将复制数据。因此,我不会说这个模型是“错误的”。Lyudmil-有不同类型的非规范化,有些比其他更容易接受。不过,在这种情况下,基于我对OP想要什么的理解(公平地说,他还不是很清楚),我非常肯定地建议不要将所有内容都捆绑在一张表中。最终,您将同时获得“基本”凭证和多个“已申请”凭证,从而导致无法具有任何有意义的FK/业务密钥约束。此外,根据我的理解,我说“似乎错了”:-。
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
)