另一个冬眠问题…:p
使用hibernate的注解框架,我有一个 User
实体。每个 User
可以收藏朋友:收藏其他朋友 User
s。但是,我还没有弄清楚如何在系统中创建多对多关联 User
由一系列 User
s(使用用户朋友中间表)。
以下是用户类及其注解:
@Entity
@Table(name="tbl_users")
public class User {
@Id
@GeneratedValue
@Column(name="uid")
private Integer uid;
...
@ManyToMany(
cascade={CascadeType.PERSIST, CascadeType.MERGE},
targetEntity=org.beans.User.class
)
@JoinTable(
name="tbl_friends",
joinColumns=@JoinColumn(name="personId"),
inverseJoinColumns=@JoinColumn(name="friendId")
)
private List<User> friends;
}
用户朋友Map表只有两列,这两列都是 uid
列 tbl_users
table。这两列是 personId
(应该Map到当前用户),以及 friendId
(指定当前用户朋友的id)。
问题是,“friends”字段总是显示为空,即使我已经预先填充了friends表,使得系统中的所有用户都是其他所有用户的朋友。我甚至试着把关系转到 @OneToMany
,它仍然显示为null(尽管hibernate debug输出显示 SELECT * FROM tbl_friends WHERE personId = ? AND friendId = ?
查询,但没有其他)。
关于如何填充这个列表有什么想法吗?谢谢您!
3条答案
按热度按时间b4wnujal1#
公认的答案似乎过于复杂
@JoinTable
注解。稍微简单一点的实现只需要mappedBy
. 使用mappedBy
表示拥有Entity
,或属性,这应该是referencesTo
因为那会被认为是“朋友”。一ManyToMany
关系可以创建一个非常复杂的图形。使用mappedBy
使代码如下:要使用它,你需要考虑拥有的财产是
referencesTo
. 您只需要将关系放在该属性中,就可以引用它们。当你读一本Entity
回来,假设你fetch join
,jpa将为结果创建集合。当您删除一个实体时,jpa将删除对它的所有引用。它提供以下日志输出(始终检查生成的sql语句):
yvfmudvl2#
其实它很简单,可以通过如下方式实现,比如说你有如下的实体
相同的hbm:
和测试用例
ny6fqffe3#
@多对多对自我是相当混乱的,因为你通常建模的方式不同于“休眠”方式。你的问题是你错过了另一个收藏。
这样想吧——如果你将“author”/“book”Map为多对多,你需要book上的“authors”集合和author上的“books”集合。在本例中,您的“用户”实体表示关系的两端;所以你需要“我的朋友”和“收藏的朋友”:
您仍然可以使用相同的关联表,但请注意,join/inversejon列在集合上是交换的。
“friends”和“friendof”集合可能匹配,也可能不匹配(取决于“friendof”是否始终是相互的),当然,您不必在api中以这种方式公开它们,但这是在hibernate中Map它们的方法。