我正在尝试优化我的@Entity
课程。让我们以User <-> Group
关系的常见情况为例。我还想存储建立关系的日期。表布局:
USER GROUP_USER GROUP
------ ------------ -------
id user_id id
name group_id name
createdAt
有以下3个类:
User
和@OneToMany List<GroupUser>
GroupUser
@ManyToOne User
和_@ManyToOne Group
Group
和@OneToMany List<GroupUser>
它可以工作,但对于常见的用例来说很糟糕。例如:给我所有组User user
:
List<Group> groups;
for(GroupUser gu : user.getGroupUsers) {
groups.add(gu.getGroup());
}
然后Map
我想到了使用 a 的想法。所以我创建了以下 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_KEY
groups_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;
}
我仍然很想看到这些注释究竟做了什么的解释,以及为什么默认行为会创建四列和一个奇怪的主键。