JPA中的多对多双向映射
Posted
技术标签:
【中文标题】JPA中的多对多双向映射【英文标题】:Many to many bidirectional mapping in JPA 【发布时间】:2014-09-16 14:08:23 【问题描述】:我有以下 JPA 实体。 一个个人资料有很多用户,一个用户有很多个人资料:
@Entity
public class Profile implements Serializable
@Id
private Long id;
@ManyToMany(cascade = CascadeType.ALL)
private List<User> users;
...
@Entity
public class User implements Serializable
@Id
private Long id;
@ManyToMany(mappedBy = "users")
private List<Profile> profiles;
...
在我的应用程序中,当用户为 merged 时,配置文件会在数据库中更新。 但是,当个人资料为merged 时,用户不会更新。
是否可以映射我的实体以使双方合并他们的列表? 我正在使用 JPA 2.1 和 Hibernate。
【问题讨论】:
您是否尝试将级联选项 CascadeType.ALL 添加到两个关系?将其放在配置文件-> 用户关系上似乎与您的描述相反,即在合并配置文件时,不会合并用户。会不会是你们双方的关系都没有维系? 也可以只有CascadeType.MERGE 感谢您的帮助。我尝试了这个解决方案,但它不起作用。可能是另一个问题。 【参考方案1】:您的Profile
实体是自己的一方或关系。由它来管理关系,所以要更新User
,您也必须更新Profile
或进行手动SQL 调用。
Java Specification for JPA 2.1 说:
• 对于多对多双向关系,任何一方都可能是拥有方
因此,如果您想让两个实体都可从两侧编辑,请删除 mappedBy
元素并分配必要级联。但我不确定它在 Hibernate 中是否有效(实际上没有尝试过),请参阅有关映射的文档,没有关于 m:m 的信息没有拥有方:http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch07.html#collections-bidirectional
否则,您可能需要遍历 Profile
实体中的集合,然后更改它们。例如:
for( User user : profile.getUsers() )
user.setSomething(.....);
session.merge(profile);
为了避免 Hibernate 的删除和重新插入,可能需要将 List 更改为 Set,如下所述:http://assarconsulting.blogspot.fr/2009/08/why-hibernate-does-delete-all-then-re.html
另外,不要忘记 equals()
和 hashCode()
方法覆盖
【讨论】:
以上是关于JPA中的多对多双向映射的主要内容,如果未能解决你的问题,请参考以下文章
Hibernate学习笔记 --- 创建基于中间关联表的多对多映射关系