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

标签 java hibernate many-to-many

在我的项目中,我需要 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/

相关文章:

java - JAVA数组中整数的差异

java - JDK8 CompletableFuture.supplyAsync如何处理interruptedException

java - 如何在方法中使用类的泛型

python - 在 django 中按 ManyToMany 关系列出标签

ios - 具有两个一对多关系的 CoreData NSPredicate

python - 从 ManyToMany 在 admin.py 中添加字段

java - 如何减少节俭膨胀

Hibernate 卡在 session.createQuery.list 处

hibernate - Hibernate 零停机时间

java - ArrayList.remove() 的意外行为