在我的项目中,我需要 2 个具有双向多对多关系的实体。但是,连接表必须与其他表有自己的额外关系,因此我自己为连接表创建了一个新实体。
它应该看起来像这样:
项目——检查器分配——用户
将检查员分配添加到项目并保留它时,该分配也应该被保留,并且用户也应该添加该分配。
为此,我在服务中有一个方法:
projectService.assignInspectorToProject(inspector, project);
但是,当我运行此方法两次时,我的表中会创建两条记录。这种情况不应该发生,因为所有集合都是集合。
有人可以指出我做错了什么吗?
所有相关方法/类:
项目服务
public void assignInspectorToProject(User user, Project project) {
if (!user.hasRole("inspector")) {
throw new RuntimeException("This user is no inspector");
}
project.addInspector(user);
projectDao.save(project);
}
项目
@Entity
public class Project extends AbstractPersistentObject {
@OneToMany(cascade = {CascadeType.ALL}, mappedBy = "project")
private Set<InspectorAssignment> inspectorAssignments;
public void addInspector(User user) {
InspectorAssignment assignment = new InspectorAssignment(user, this);
user.addInspectorAssignment(assignment);
inspectorAssignments.add(assignment);
}
}
检查员分配
@Entity
public class InspectorAssignment extends AbstractPersistentObject {
@ManyToOne
@NotNull
private User user;
@ManyToOne
@NotNull
private Project project;
public InspectorAssignment() {
}
public InspectorAssignment(User user, Project project) {
setUser(user);
setProject(project);
}
}
用户
@Entity
public class User extends AbstractPersistentObject implements UserDetails {
@OneToMany(mappedBy = "user", cascade = {CascadeType.ALL})
private Set<InspectorAssignment> inspectorAssignments;
public void addInspectorAssignment(InspectorAssignment assignment) {
inspectorAssignments.add(assignment);
}
}
}
AbstractPersistenObject 中的 equals 和 hashcode 方法(我所有实体扩展的类)
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AbstractPersistentObject other = (AbstractPersistentObject) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (id.equals(other.id))
return true;
return false;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
最佳答案
这对我来说似乎很合乎逻辑。您调用此方法两次。因此,您创建了两个不同的 InspectorAssignment 实例并保存它们。即使您通过保存项目来保存它们,项目也会有一组包含两个不同 InspectorAssignment 实例的分配。如果第二个等于第一个,则 Set 不会添加第二个,但事实并非如此,因为您还没有覆盖 hashCode()
和 equals()
。
我愿意
- 在分配表中对
userId-projectId
创建唯一约束,以确保不会发生这种情况并引发异常 - 仅在新的 InspectorAssignment 尚不存在时创建它
- 通过显式保存来在数据库中创建 InspectorAssignment,而不是依赖从 Project 到 InspectorAssignment 的级联
- 覆盖 InspectorAssignment 中的
equals()
和hashCode()
关于java - hibernate 中具有自定义实体的多对多 - 级联无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10665827/