在hibernate中有许多自定义实体 - 级联无法正常工作

时间:2012-05-19 14:04:05

标签: java hibernate many-to-many

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

它应该是这样的:

项目 - InspectorAssignment - 用户

在将一个inspectorassignment添加到项目并持久保存时,也应该保留该分配,并且用户也应该添加分配。

要做到这一点,我在服务中有一个方法:

projectService.assignInspectorToProject(inspector, project);

然而,当我运行此方法时,会在我的表中创建两次两个记录。这不应该发生,因为所有集合都是集合。

有人能指出我做错了吗?

所有相关方法/类:

ProjectService

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

InspectorAssignment

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

1 个答案:

答案 0 :(得分:2)

这对我来说似乎很合乎逻辑。你两次调用这个方法。因此,您创建两个不同的InspectorAssignment实例并将它们保存。即使您通过保存项目来保存它们,项目也会有一组包含两个不同InspectorAssignment实例的分配。 Set不会添加第二个,它等于第一个,但它没有,因为你没有覆盖hashCode()equals()

我会

  • 在分配表中的userId-projectId上创建一个唯一约束,以确保它不会发生并引发异常
  • 只创建一个新的InspectorAssignment(如果它还不存在)
  • 通过明确保存InspectorAssignment来创建InspectorAssignment,而不是依靠从Project到InspectorAssignment的级联
  • 在InspectorAssignment中覆盖equals()hashCode()