首页 > 解决方案 > 带有额外列的多对多,但在额外列是列表的情况下分组在一起

问题描述

我有一个连接表,其中包含一个额外的列,用于用户和项目之间的多对多关系。它看起来像这样:

user_id (pk) project_id (pk) 角色(PK)
1 1 经理
2 1 工人
1 2 经理
1 2 工人

在这个例子中,项目 1 有两个参与者,用户 1 在那里,角色为经理,用户 2 在那里,角色为工人。在项目 2 中,只有一个参与者,用户 1,它扮演经理和工人的角色。

我想要完成的是这样的 Java 表示:

@Entity(...)
class ProjectRole {
    // some annotations
    private User user;

    // some annotations
    private Project project;
    
    // some annotations
    private Set<String> roles;

    // getters and setters
}

我知道获得这样一个对象的两种间接方法。

备选方案 1:将表的实体映射为:

@Id
@ManyToOne
@JoinColumn(name = "user_id")
User user;

@Id
@ManyToOne
@JoinColumn(name = "project_id")
Project project;

@Id
String role;

并为同一用户(每个项目)组合多个命中并将其映射到像上面想要的结构这样的对象,但这将不允许在将来使用排序或分页,直接获取目标结构会很好。

备选方案 2:我可以使用人工创建一个人工表participants并将其participant.id用于participant_roles表中。所以我得到了两个实体,而第一个实体可以有一个Set<ParticipantRole>. 但是我必须在数据库中保存很多不必要的信息。

也许这是不可能的,因为实体实例或多或少是数据库中一行的表示,所以我总是会为每个用户(每个项目)获得多个条目。或者有什么我到目前为止还没有看到的东西来完成它?

标签: javasqlhibernatejpamany-to-many

解决方案


只需使用选项 1 并通过一些按需或在@PostLoad事件侦听器中进行分组的专用方法公开详细信息。Hibernate/JPA 需要信息是双向的,你想要的映射类型或多或少是标准化数据的投影。


推荐阅读