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中的多对多双向映射的主要内容,如果未能解决你的问题,请参考以下文章

JPA多对多映射

一口一口吃掉Hibernate——多对多关联映射

Hibernate学习笔记 --- 创建基于中间关联表的多对多映射关系

JPA 2:通过不在带有额外字段的多对多中工作来订购

Hibernate,关系映射的多对一单向关联多对一双向关联一对一主键关联一对一外键关联多对多关系关联

hibernate多对多关联映射