我在两个实体之间有@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;
...
}
答案 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)
看来我的问题是我没有合并该实体。