Java hibernate中具有自定义实体的多对多-级联无法正常工作

Java hibernate中具有自定义实体的多对多-级联无法正常工作,java,hibernate,many-to-many,Java,Hibernate,Many To Many,在我的项目中,我需要两个具有双向多对多关系的实体。但是,联接表必须与其他表有自己的额外关系,因此我自己为联接表创建了一个新实体 应该是这样的: 项目——检查员分配——用户 将inspectorassignment添加到项目并将其持久化时,分配也应持久化,用户也应添加分配 为此,我在服务中有一个方法: projectService.assignInspectorToProject(inspector, project); 但是,当我运行此方法两次时,会在表中创建两条记录。这不应该发生,因为所有集

在我的项目中,我需要两个具有双向多对多关系的实体。但是,联接表必须与其他表有自己的额外关系,因此我自己为联接表创建了一个新实体

应该是这样的:

项目——检查员分配——用户

将inspectorassignment添加到项目并将其持久化时,分配也应持久化,用户也应添加分配

为此,我在服务中有一个方法:

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);
     }
}
}

我觉得这很合乎逻辑。你调用这个方法两次。因此,您创建了两个不同的InspectorAssignment实例并将其保存。即使通过保存项目来保存它们,项目也有一组包含两个不同的InspectorAssignment实例的指定。集合不会添加第二个,因为它等于第一个,但它不是,因为您没有重写
hashCode()
equals()

我会的

  • 在分配表中的
    userId projectId
    上创建唯一约束,以确保不会发生这种情况,并引发异常
  • 仅当新的InspectorAssignment不存在时才创建它
  • 在数据库中创建InspectorAssignment,方法是明确地保存它,而不是依赖于从项目到InspectorAssignment的级联
  • 在InspectorAssignment中重写
    equals()
    hashCode()

也许您需要一些标识属性……我忘了提到我有这些属性,它们在我要扩展的AbstractPersistentObject中。我已经更新了我的帖子,并添加了equals和hashcode方法。我将自己持久化InspectorAssignment,这样它就会得到一个id,而equals将返回true。谢谢:)Hibernate建议不要使用自动生成的ID来实现equals和hashCode(尽管通常很难做到)。但请注意,如果您的实体没有ID,而您将其添加到集合中,您将遇到问题。如果有人愿意看看我的问题,我将非常高兴,因为我无法进行多对多更新。非常感谢。
 @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;
}