gpt4 book ai didi

hibernate - 使用 @ElementCollection 和 java.util.Map 的 ManyToMany(带有附加列)?

转载 作者:行者123 更新时间:2023-12-02 06:27:37 25 4
gpt4 key购买 nike

我正在尝试优化我的 @Entity类。让我们以 User <-> Group 为例。关系。我还想存储建立关系的日期。表格布局:

 USER      GROUP_USER      GROUP
------ ------------ -------
id user_id id
name group_id name
createdAt

具有以下 3 个类:

  1. User@OneToMany List<GroupUser>
  2. GroupUser@ManyToOne User@ManyToOne Group
  3. Group@OneToMany List<GroupUser>

它可以工作,但对于常见用例来说它很糟糕。例如:给我 User user 的所有组:

List<Group> groups;
for(GroupUser gu : user.getGroupUsers) {
groups.add(gu.getGroup());
}
<小时/>

然后是使用 Map 的想法我想到了。所以我创建了以下 3 个类:

@Entity
class User {
@Column(name="id")
UUID id;

@Column(name="name")
String name;

@ElementCollection
@CollectionTable(name="Group_User")
Map<Group, GroupUserRelationData> groups;
}

@Entity
class Group {
@Column(name="id")
UUID id;

@Column(name="name")
String name;

@ElementCollection
@CollectionTable(name="Group_User")
Map<User, GroupUserRelationData> users;
}

@Embeddable
class GroupUserRelationData {
@Column(name="createdAt")
DateTime createdAt;
}

确实按预期创建了 3 个表,但 Group_User 内的列表格很奇怪:

 USER      GROUP_USER      GROUP
------ ------------ -------
id User_id id
name users_KEY name
Group_id
group_KEY
createdAt

我确定我遗漏了一些东西...看起来我必须指定 JoinColumn。但什么是正确的方法呢?

@CollectionTable(joinColumns=...) 和有什么区别和@MapKeyColumn@MapKeyJoinColumn 。我必须设置所有这些吗?

或者我必须使用 @ManyToMany而不是@ElementCollection

我只想使用 java.util.Map 获得与顶部相同的表格布局.

<小时/>

编辑#1:此外,数据库之后应该对表有正确的约束:

  • 复合主键(Group_id、User_id)

目前它创建了一个复合 PK(Group_id,users_KEY),这对我来说似乎很奇怪。它还创建 4(!!) 个索引,每列一个 User_id , Group_id , users_KEYgroups_KEY .

<小时/>

编辑#2:我找到了一个网站,它告诉我们何时使用哪些注释:http://kptek.wordpress.com/2012/06/26/collection-mapping/

糟糕的是:我仍然不知道为什么...

解决方案:

经过一番尝试,我想出了以下代码,它正是我想要的。我必须使用所有这些注释,否则它会创建额外的列:

@Entity
class User {
@Column(name="id")
UUID id;

@Column(name="name")
String name;

@ElementCollection
@CollectionTable(name="Group_User",
joinColumns=@JoinColumn(name="User_Id"))
@MapKeyJoinColumn(name="Group_Id")
Map<Group, GroupUserRelationData> groups;
}

@Entity
class Group {
@Column(name="id")
UUID id;

@Column(name="name")
String name;

@ElementCollection
@CollectionTable(name="Group_User",
joinColumns=@JoinColumn(name="Group_Id"))
@MapKeyJoinColumn(name="User_Id")
Map<User, GroupUserRelationData> users;
}

@Embeddable
class GroupUserRelationData {
@Column(name="createdAt")
DateTime createdAt;
}

我仍然希望看到这些注释的确切用途的解释,以及为什么默认行为创建了四个列和一个奇怪的主键。

最佳答案

Map 需要一对多键和映射键。

在第一个示例中,Hibernate 发现它需要来自 Group.id 的 FK 来匹配 GroupUser.group_id 来加载关联的用户。但是因为您没有指定 Map 键,所以它必须找出 where to take it from

因此,Hibernate 假定您需要一个 @MapKeyColumn 并且由于未指定列名,因此使用属性名称后跟下划线,后跟 KEY(例如 users_KEY)。

这就是为什么你有这两个额外的列。当您提供 @MapKeyJoinColumn(name="User_Id") 时,Map 就知道从哪里获取 key 。

关于hibernate - 使用 @ElementCollection 和 java.util.Map 的 ManyToMany(带有附加列)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18975312/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com