且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-12-05 21:01:46

我按照我期望的方式执行插入操作。感谢Pascal和z5h,我学到了很多东西。我相信我有hashCode和等于正确实施。尽管如此,这从来没有解决过这个问题。相反,我已经实施了一个中间实体。



以下是我的员工,CohortGroup和现在的CohortGroupMemeber类中的映射。



Employee:

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

CohortGroupMember

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

CohortGroup

  @OneToMany(mappedBy =group)
public List< CohortGroupMember> getMembers(){
返回成员;
}
public void setMembers(List< CohortGroupMember> emps){
members = emps;

我遵循的这本书是Java Persistence with Hibernate chapter 7.2.3


I have a many to may relationship CohortGroup and Employee. Any time I insert an Employee into the CohortGroup hibernate deletes the group from the resolution table and inserts all the members again, plus the new one. Why not just add the new one?

The annotation in the Group:

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

The other side in the Employee

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

Code snipit

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

below is the sql reported in the log

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 (?, ?)

This seams really inefficient and is causing some issues. If sevral requests are made to add an employee to the group then some get over written.

Seams like equals and hashCode might be a reason for this. Below are the implementation for these methods. Any red flags?

CohortGroup

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

Employee

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

I have added an addMember method to the CohortGroup that adds to both sides of the relationship:

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

}

Continued thanks to all that are helping.

I have inserts acting the way I expect them to now. Thanks to Pascal and z5h, I have learned a lot. I believe I have the hashCode and equals implemented correctly. This never solved the problem for me though. Instead I have implemented an Intermediate Entity.

For what it is worth below are the mapping in my Employee, CohortGroup, and now CohortGroupMemeber classes.

Employee:

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

CohortGroupMember

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

CohortGroup

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

The book I followed for this is Java Persistence with Hibernate chapter 7.2.3