web-dev-qa-db-ja.com

Hibernate @OneToManyは親を更新するときにリストから子を削除します

次のエンティティがあります。

チーム

_@Entity
@Table
public class Team {
[..]
private Set<UserTeamRole> userTeamRoles;

/**
 * @return the userTeamRoles
 */
@OneToMany(cascade = { CascadeType.ALL }, mappedBy = "team", fetch = FetchType.LAZY)
public Set<UserTeamRole> getUserTeamRoles() {
    return userTeamRoles;
}

/**
 * @param userTeamRoles
 *            the userTeamRoles to set
 */
public void setUserTeamRoles(Set<UserTeamRole> userTeamRoles) {
    this.userTeamRoles = userTeamRoles;
}
_

}

そして

USER_TEAM_ROLE

_@Entity
@Table(name = "user_team_role")
public class UserTeamRole {

 @ManyToOne(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
 @JoinColumn(name = "FK_TeamId")
 public Team getTeam() {
    return team;
 }
}
_

現在、たとえばTeam.userTeamRoles = {UTR1、UTR2}を{UTR1、UTR3}で含むTeamエンティティを更新するとき、UTR2を削除したいのです。しかし、今のやり方では、古いリストは同じままで、リストにUTR3を追加するだけです。

これは私が現時点でそれを行う方法です:

_ if (!usersDualListData.getTarget().isEmpty()) {
        // the role for each user within the team will be "employee"
        team.setUserTeamRoles(new HashSet<UserTeamRole>());
        Role roleForUser = roleService
                .getRoleByName(RoleNames.ROLE_EMPLOYEE.name());
        for (User user : usersDualListData.getTarget()) {
            UserTeamRole utr = new UserTeamRole();
            utr.setUser(user);
            utr.setTeam(team);
            utr.setRole(roleForUser);
            team.getUserTeamRoles().add(utr);
        }
    }

teamService.updateTeam(team);
_

team.setUserTeamRoles(new HashSet<UserTeamRole>());を実行すると、リストがリセットされ、カスケードのために前のリストが削除されると思いました。

どんな助けも大歓迎です。ありがとうございました

31
AndaP
  1. コレクション(team.setUserTeamRoles(new HashSet<UserTeamRole>());)を置き換える代わりに、既存のコレクションをclear()する必要があります。これは、HibernateがDBからエンティティ(およびそのコレクション)をロードすると、それらを「管理」するためです。変更を追跡します。一般に、Hibernateを使用する場合は、コレクション(リスト、セット)のセッターを作成する方が良いですnot。ゲッターのみを作成し、それによって返されるコレクションをクリアします。つまり:

    team.getUserTeamRoles().clear();

  2. もう1つは、孤立した削除を逃すことです(つまり、親のコレクションから子オブジェクトが削除されたときに子オブジェクトを削除します)。有効にするには、所有エンティティに@OneToMany(orphanRemoval=true)を追加する必要があります。

92
Adam Dyga