2

我试图找出@ManyToMany在 Hibernate 中映射三向关系的最佳方法。以下是我的数据模型:

在此处输入图像描述

如您所见,TeamPosition 表只不过是 3 个外键。Hibernate 以两个表之间的多对多映射的形式提供了有用的功能,并且在不需要创建第三个 Hibernate 实体的情况下连接它们的映射表。当然,如果该映射表有额外的数据,例如“StartDate”、“EndDate”,那么无论如何都需要为映射表创建实体。

是否可以在每个实体上为其他两个实体创建两个 ManyToMany 映射,或者如果我创建一个 TeamPosition 实体并与之建立 OneToMany 关系,它会更简单、更不痛苦吗?

我不一定认为有错误的答案,但有些答案可能比其他答案更正确。

4

1 回答 1

1

有趣的问题!

为了清楚起见:这部分数据库是否记录了特定球队在特定赛季所在的联赛组?这里的“联盟组”是什么意思?就像,英超联赛vs冠军vs联赛第一?在给定的赛季中,给定的联赛组中可以有几支球队吗?

我怀疑制作TeamPosition实体将是最不痛苦的事情。这些关系都是一对多的,您可以使用它的外键TeamSeason构造复合主键,这样就无需为表提供冗余代理键。通过表连接的查询必须明确命名,但相当简单。

但是,您也可以尝试将其建模为地图。看起来像:

public class Team {
    @ManyToMany
    private Map<Season, LeagueGroup> positions;
}

不保证安全。我以前只做过一次。如果你从上面生成 SQL(在我的例子中使用 Hibernate 的模式生成器),你会得到以下连接表(我给了我的实体整数键):

create table Team_LeagueGroup (
    Team_id integer not null,
    positions_id integer not null,
    positions_KEY integer not null,
    primary key (Team_id, positions_KEY)
);

使用以下外键使其更清晰:

alter table Team_LeagueGroup 
    add constraint FKE143A2AEB84635C9 
    foreign key (Team_id) 
    references Team;

alter table Team_LeagueGroup 
    add constraint FKE143A2AEB7412E91 
    foreign key (positions_id) 
    references LeagueGroup;

alter table Team_LeagueGroup 
    add constraint FKE143A2AE8F6AD5C 
    foreign key (positions_KEY) 
    references Season;

这看起来是对的。您可以使用通常的注释来自定义您认为合适的表和列名称。

现在,这避免了为连接表创建实体的需要,但它还有一些不足之处。首先,我不知道用于连接的 JPQL 语法是什么。它会在文档中,但你肯定会得到你的童子军徽章来探索规范的晦涩角落以找到它。其次,我认为没有任何方法可以为此设置反向映射。问题在于,尽管球队和赛季的组合唯一地标识了一个联赛组,但对于这三对中的其他组合来说,情况并非如此。一个给定的球队可能在几个赛季都在一个给定的联赛组中,并且在一个给定的赛季中的一个给定的联赛组将包含几支球队。反向关系需要看起来像class LeagueGroup { Map<Season, Set<Team>> teams; },我认为这超出了 JPA 的能力(尽管我可能是错的)。

于 2012-07-24T21:32:39.260 回答