一尘不染

将hibernate插入到集合中会导致删除,然后再次插入集合中的所有项目

hibernate

我与CohortGroup和Employee有很多关系。每当我将Employee插入CohortGroup时,hibernate都会从解析表中删除该组,然后再次插入所有成员以及新成员。为什么不只是添加新的呢?

组中的注释:

@ManyToMany(cascade = { PERSIST, MERGE, REFRESH })
@JoinTable(name="MYSITE_RES_COHORT_GROUP_STAFF",
joinColumns={@JoinColumn(name="COHORT_GROUPID")},
inverseJoinColumns={@JoinColumn(name="USERID")})
public List<Employee> getMembers(){
  return members;
}

员工的另一边

@ManyToMany(mappedBy="members",cascade = { PERSIST, MERGE, REFRESH } )
public List<CohortGroup> getMemberGroups(){
  return memberGroups;
}

代码嗅探

Employee emp = edao.findByID(cohortId);
CohortGroup group = cgdao.findByID(Long.decode(groupId));
group.getMembers().add(emp);
cgdao.persist(group);

下面是日志中报告的SQL

delete from swas.MYSITE_RES_COHORT_GROUP_STAFF where COHORT_GROUPID=?
insert into swas.MYSITE_RES_COHORT_GROUP_STAFF (COHORT_GROUPID, USERID) values (?, ?)
insert into swas.MYSITE_RES_COHORT_GROUP_STAFF (COHORT_GROUPID, USERID) values (?, ?)
insert into swas.MYSITE_RES_COHORT_GROUP_STAFF (COHORT_GROUPID, USERID) values (?, ?)
insert into swas.MYSITE_RES_COHORT_GROUP_STAFF (COHORT_GROUPID, USERID) values (?, ?)
insert into swas.MYSITE_RES_COHORT_GROUP_STAFF (COHORT_GROUPID, USERID) values (?, ?)
insert into swas.MYSITE_RES_COHORT_GROUP_STAFF (COHORT_GROUPID, USERID) values (?, ?)

这种接缝的效率很低,并且会引起一些问题。如果有人提出要求将雇员添加到组中,则有些人将其改写。

诸如equals和hashCode之类的接缝可能是造成这种情况的原因。下面是这些方法的实现。有没有危险信号?

同类群组

    @Override
public int hashCode() {
    final int prime = 31;
    int result = getName().hashCode();
    result = prime * result + ((emp == null) ? 0 : emp.hashCode());
    return result;
}
@Override
public boolean equals(Object obj) {
    if (this == obj) {return true;}
    if (!(obj instanceof CohortGroup)) {return false;}
    CohortGroup other = (CohortGroup) obj;
    if(!getName().equals(other.getName())){return false;}
    if (emp == null && other.getOwner() != null) {
        return false;
    } else if (!emp.equals(other.getOwner())) {
        return false;
    }
    return true;
}

雇员

       @Override
public boolean equals(Object obj) {
    if (this == obj) {return true;}
    if (obj == null) {return false;}
    if (!(obj instanceof Employee)) {return false;}
    Employee other = (Employee) obj;
    if (EMPLID == null && other.getEMPLID() != null) {
        return false;
    } else if (!EMPLID.equals(other.getEMPLID())) {
        return false;
    }
    return true;
}

   @Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((EMPLID == null) ? 0 : EMPLID.hashCode());
    return result;
}

我向CohortGroup添加了addMember方法,该方法同时添加到关系的两侧:

    public void addMember(Employee emp){
    this.getMembers().add(emp);
    emp.getMemberGroups().add(this);

}

继续感谢所有正在提供的帮助。


阅读 195

收藏
2020-06-20

共1个答案

一尘不染

我有插入片段,以现在期望的方式运行。感谢Pascal和z5h,我学到了很多东西。我相信我的hashCode和equals正确实现。但这从来没有为我解决问题。相反,我实现了一个中间实体。

对于下面的内容,我的Employee,CohortGroup和现在的CohortGroupMemeber类中的映射是值得的。

雇员:

@OneToMany(mappedBy="member")
public List<CohortGroupMember> getMemberGroups(){
   return memberGroups;
}
public void setMemberGroups(List<CohortGroupMember> grps){
   memberGroups = grps;
}

同类群组成员

@ManyToOne
@JoinColumn(name="USERID")
public Employee getMember(){
    return emp;
}
public void setMember(Employee e){
    emp = e;
}
@ManyToOne
@JoinColumn(name="COHORT_GROUPID")
public CohortGroup getGroup(){
    return group;
}
public void setGroup(CohortGroup cg){
    group   = cg;
}

同类群组

@OneToMany(mappedBy="group")
public List<CohortGroupMember> getMembers(){
    return members;
}
public void setMembers(List<CohortGroupMember> emps){
    members = emps;
}

我为此编写的书是《 Java Persistence with Hibernate》第7.2.3章。

2020-06-20