JPA更新多对多删除记录
我在两个实体之间有@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 types; ... } @Entity public class UserType { @Id @Column(name="type_id") private String id; @ManyToMany(mappedBy="types") private List users; ... }
使用Set
而不是List
解决了问题。 但我不知道它为什么会起作用。
Hibernate提供的另一个解决方案是将@ManyToMany
关联分成两个双向@OneTo@Many
关系。 例如,请参阅Hibernate 5.2文档 。
如果双向
@OneToMany
关联在删除或更改子元素的顺序时表现更好,则@ManyToMany
关系无法从这种优化中受益,因为外键端不受控制。 要克服此限制,必须直接公开链接表,并将@ManyToMany
关联拆分为两个双向@OneToMany
关系。
它可能与这个问题有关 。 您必须确保在映射对象中具有适当定义的hashCode和equals方法,以便Eclipselink可以确定相等性,从而确定现有对象映射到DB中的现有对象。 否则它别无选择,只能每次都重新创建子对象。
或者,我已经读过,如果使用索引列,这种连接只能支持有效添加和删除列表项,但这将是EclipseLink特定的,因为JPA注释似乎不支持这样的事情。 我知道有一个等效的Hibernate注释,但我不知道它在Eclipselink中会是什么,如果这样的事情存在的话。
试试这个:
1)将声明变更为:
private List types = new Vector ();
2)永远不要打电话
user.setTypes(newTypesList)
3)只打电话
user.getTypes().add(...); user.getTypes().remove(...);
看来我的问题是我没有合并该实体。