JPA更新多对多删除记录

时间:2010-08-17 15:51:33

标签: java mysql jpa eclipselink jpa-2.0

我在两个实体之间有@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 个答案:

答案 0 :(得分:3)

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

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

  

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

答案 1 :(得分:1)

它可能与此question有关。您必须确保在映射对象中具有正确定义的hashCode和equals方法,以便Eclipselink可以确定相等性,从而确定现有对象映射到DB中的现有对象。否则它别无选择,只能每次都重新创建子对象。

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

答案 2 :(得分:1)

试试这个:

1)将声明更改为:

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

2)永远不要打电话

user.setTypes(newTypesList)

3)只打电话

user.getTypes().add(...);
user.getTypes().remove(...);

答案 3 :(得分:0)

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