【问题标题】:Multiple @ManyToMany sets from one join table来自一个连接表的多个 @ManyToMany 集
【发布时间】:2009-11-19 09:09:12
【问题描述】:

我正在将专有数据库映射到 Hibernate 以与 Spring 一起使用。其中,有几个可连接对象,对于实体 A 和实体 B,具有以下模式:

CREATE TABLE AjoinB (
  idA int not null,
  idB int not null,
  groupEnum enum ('groupC', 'groupD', 'groupE'),
  primary key(idA, idB, groupEnum)
);

如您所见,这表明可以有多个 A-B 关系将它们放在不同的组中。我想结束,实体 A 的第一行和实体 B 的第二行,以下集合

Set<B> BforGroupC, BforGroupD, BforGroupE;
Set<A> AforGroupC, AforGroupD, AforGroupE;

到目前为止,我只设法将它们放在一组中并忽略 groupEnum 关系属性:

@ManyToMany(targetEntity=B.class, cascade={ CascadeType.PERSIST, CascadeType.MERGE } )
@JoinTable(name="AjoinB", joinColumns=@JoinColumn(name="idA"), inverseJoinColumns=@JoinColumn(name="idB") )
private Set<B> BforAllGroups;

@ManyToMany( mappedBy = "BforAllGroups", targetEntity = A.class )
private Set<A> AforAllGroups;

如何在 groupC、groupD 或 groupE 中创建多个集合?

干杯

尼克

【问题讨论】:

  • 在 Join 上做类似@DiscriminatorColumn(name="groupEnum", discriminatorType=ENUM) @DiscriminatorValue("groupC") 会很漂亮:-)

标签: java hibernate spring many-to-many jointable


【解决方案1】:

如果您考虑这样做,请不要这样做。如今,随着经济的发展,桌子很便宜,所以只需为每个协会创建一张;会轻松很多。

如果您受旧数据库的约束并且无法更改该表的结构,我会

  1. 首先考虑 skaffman 的解决方案(+1,顺便说一句)。根据您的目标数据库,您可能能够为您的视图编写一个触发器,该触发器将插入足够的“鉴别器”值。

  2. 如果在您的数据库中无法实现上述操作,另一种解决方案是为您的集合使用 custom SQL for CRUD operations。请记住,对于涉及您的关联作为条件的一部分的复杂 HQL 查询,这将起作用(例如,您的“鉴别器值”不会被应用)。您也可以将其与上述混合/匹配 - 例如使用视图并使用自定义 SQL 进行插入/删除。

  3. 如果上述两种方法都失败,请按照 framer8 的建议使用“作为单独实体的关联”。由于复合键和所有无关代码,这将是相当难看的(因为我们在这里假设您不能更改表)。事实上,如果您的任何关联允许重复,这可能是不可能的。

【讨论】:

  • 奇怪的是,像关系上的属性这样简单的事情在 Hibernate 中却如此困难,所以我在上面提交了一个错误。我将寻求的解决方法是您的答案中的#1 和#2 的混合。非常感谢您的意见:-)
【解决方案2】:

据我所知,Hibernate 不能以您想要的方式使用这样的“鉴别器”列。 Hibernate 需要一个连接表。

也许您可以在表格上定义其他视图,显示每个分组?

【讨论】:

  • 嗨,斯卡夫曼,感谢您的建议。如果我定义视图“CREATE VIEW viewAjoinBgroupC AS SELECT idA, idB FROM AjoinB WHERE groupEnum='groupC'”,那么任何插入到我的集合中的内容都将类似于“插入 viewAjoinBgroupC VALUES (2,3);”,从而给我一个无效条目(2,3,'groupC')。如果您对如何克服这个问题有建议,那么这是一种可行的解决方法。干杯-尼克
【解决方案3】:

我认为任何时候需要访问链接表中的字段的建议是使链接表本身成为一个对象和一个休眠实体。 A 将有一组 AtoB 对象,而 AtoB 将有一组 B 对象。我有一个类似的情况,链接表有一个与链接关联的用户。

select joinTable.b from A a 
left join a.AtoB joinTable
where joinTable.group = 'C'

它不像休眠完成的隐式连接那样优雅,但它确实为您提供了所需的控制。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-20
    • 2016-12-10
    • 1970-01-01
    相关资源
    最近更新 更多