3

我在两个实体之间有 @ManyToMany 关系。当我在拥有方执行更新时,JPA 似乎从我的数据库中删除了所有链接的记录并重新插入它们。对我来说这是一个问题,因为我有一个 MySQL 触发器,它在删除记录之前触发。关于如何解决这个问题的任何想法?

@Entity
public class User {

    @Id
    @Column(name="username")
    private String username;

    ...

    @ManyToMany
    @JoinTable(name="groups", joinColumns=
        @JoinColumn(name="username", referencedColumnName="username"),
            inverseJoinColumns=@JoinColumn(name="groupname",
                    referencedColumnName="type_id"))
    private List<UserType> types;

    ...

}

@Entity
public class UserType {

    @Id
    @Column(name="type_id")
    private String id;

    @ManyToMany(mappedBy="types")
    private List<User> users;

    ...
} 
4

4 回答 4

3

使用Set而不是List解决问题。但我不知道为什么它会起作用。

Hibernate 提供的另一个解决方案是将@ManyToMany关联拆分为两个双向@OneTo@Many关系。例如,请参阅Hibernate 5.2 文档

如果双向@OneToMany关联在删除或更改子元素的顺序时表现更好,则@ManyToMany 关系无法从这种优化中受益,因为外键端不受控制。为了克服这个限制,必须直接公开链接表,并将@ManyToMany关联拆分为两个双向@OneToMany关系。

于 2017-10-23T10:49:00.183 回答
2

试试这个:

1)将声明更改为:

private List<UserType> types = new Vector<UserType>();

2) 从不打电话

user.setTypes(newTypesList)

3)只打电话

user.getTypes().add(...);
user.getTypes().remove(...);
于 2010-08-18T08:29:06.433 回答
1

它可能与这个问题有关。您必须确保在映射对象中有适当定义的 hashCode 和 equals 方法,以便 Eclipselink 可以确定相等性,从而确定现有对象映射到数据库中的现有对象。否则它别无选择,只能每次都重新创建子对象。

或者,我已经读到,如果您使用索引列,这种连接只能支持有效添加和删除列表项,但这将是 EclipseLink 特定的,因为 JPA 注释似乎不支持这样的事情。我知道有一个等效的 Hibernate 注释,但我不知道在 Eclipselink 中它会是什么,如果这样的东西存在的话。

于 2010-08-17T15:56:30.287 回答
1

看来我的问题是我没有合并实体。

于 2010-08-18T17:01:35.083 回答