Hibernate与同一实体的递归多对多关联
另一个 Hibernate 问题... :P
使用 Hibernate 的注释框架,我有一个 User
实体。每个用户
可以有一个朋友的集合:其他用户
的集合。但是,我无法弄清楚如何在由 User
列表组成的 User
类中创建多对多关联(使用 user-朋友中间表)。
以下是 User 类及其注释:
@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;
}
用户好友映射表只有两列,这两列都是 tbl_users
表的 uid
列的外键。两列是 personId
(应映射到当前用户)和 friendId
(指定当前用户好友的 ID)。
问题是,“朋友”字段始终为空,即使我已经预先填充了朋友表,以便系统中的所有用户都是所有其他用户的朋友。我什至尝试将关系切换为 @OneToMany,但它仍然为 null(尽管 Hibernate 调试输出显示 SELECT * FROM tbl_friends WHERE personId = ? ANDfriendId = ?
代码>查询,但没有其他)。
关于如何填充此列表有什么想法吗?谢谢你!
Another Hibernate question... :P
Using Hibernate's Annotations framework, I have a User
entity. Each User
can have a collection of friends: a Collection of other User
s. However, I have not been able to figure out how to create a Many-to-Many association within the User
class consisting of a list of User
s (using a user-friends intermediate table).
Here's the User class and its annotations:
@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;
}
The user-friend mapping table has only two columns, both of which are foreign keys to the uid
column of the tbl_users
table. The two columns are personId
(which should map to the current user), and friendId
(which specifies the id of the current user's friend).
The problem is, the "friends" field keeps coming out null, even though I've pre-populated the friends table such that all the users in the system are friends with all the other users. I've even tried switching the relationship to @OneToMany
, and it still comes out null (though the Hibernate debug output shows a SELECT * FROM tbl_friends WHERE personId = ? AND friendId = ?
query, but nothing else).
Any ideas as to how to populate this list? Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
@ManyToMany to self 相当令人困惑,因为您通常对此进行建模的方式与“Hibernate”方式不同。您的问题是您缺少另一个集合。
可以这样想 - 如果您将“作者”/“书籍”映射为多对多,则需要书籍上的“作者”集合和作者上的“书籍”集合。在这种情况下,您的“用户”实体代表关系的两端;因此您需要“我的朋友”和“朋友的”集合:
您仍然可以使用相同的关联表,但请注意 join / inverseJon 列在集合上交换。
“friends”和“friendOf”集合可能匹配也可能不匹配(取决于您的“友谊”是否始终是相互的),当然,您不必在 API 中以这种方式公开它们,但这就是映射的方式它处于休眠状态。
@ManyToMany to self is rather confusing because the way you'd normally model this differs from the "Hibernate" way. Your problem is you're missing another collection.
Think of it this way - if you're mapping "author" / "book" as many-to-many, you need "authors" collection on Book and "books" collection on Author. In this case, your "User" entity represents both ends of a relationship; so you need "my friends" and "friend of" collections:
You can still use the same association table, but note that join / inverseJon columns are swapped on collections.
The "friends" and "friendOf" collections may or may not match (depending on whether your "friendship" is always mutual) and you don't have to expose them this way in your API, of course, but that's the way to map it in Hibernate.
使用
@JoinTable
注释,接受的答案似乎过于复杂。稍微简单一点的实现只需要一个mappedBy
。使用mappedBy
表示拥有Entity
或属性,它可能应该是referencesTo
,因为它会被视为“朋友”。ManyToMany
关系可以创建非常复杂的图。使用mappedBy
使代码如下:要使用它,您需要考虑拥有属性是
referencesTo
。您只需将关系放入该属性中即可引用它们。当您读回Entity
时,假设您执行fetch join
,JPA将为结果创建集合。当您删除实体时,JPA 将删除对其的所有引用。它给出以下日志输出(始终检查生成的 SQL 语句):
The accepted answer seems overly complicated with the
@JoinTable
annotations. A slightly simpler implementation needs only amappedBy
. UsingmappedBy
indicates the owningEntity
, or property, which should probably be thereferencesTo
since that would be considered the "friends". AManyToMany
relationship can create a very complicated graph. UsingmappedBy
makes the code as so:And to use it you need to consider the owning property is the
referencesTo
. You only need to put relationships in that property in order for them to be referenced. When you read anEntity
back, assuming you do afetch join
, JPA will create the collections for the result. When you delete an Entity, JPA will delete all the references to it.Which gives the following log output (always check the generated SQL statements):
实际上它非常简单,可以通过以下方式实现:假设您有以下
相同的实体 HBM:
和测试用例
Actually its very simple and could be achieved by following say you have following entity
HBM for same:
And test case