更新父级时休眠@OneToMany 从列表中删除子级 [英] Hibernate @OneToMany remove child from list when updating parent

查看:47
本文介绍了更新父级时休眠@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

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} 的团队实体时,我希望删除 UTR2.但是我现在这样做的方式是,旧列表保持不变,只是将 UTR3 添加到列表中.

Now, when updating a Team entity that contains for example Team.userTeamRoles = {UTR1, UTR2} with {UTR1, UTR3}, I want UTR2 to be deleted. But the way I do it now, the old list remains the same and it only adds UTR3 to the list.

这就是我目前的做法:

 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()); 列表将被重置,并且由于级联,之前的列表将被删除.

I thought that by doing team.setUserTeamRoles(new HashSet<UserTeamRole>()); the list would be reset and because of the cascades the previous list would be deleted.

感谢任何帮助.谢谢

推荐答案

  1. 不是替换集合 (team.setUserTeamRoles(new HashSet());),您必须clear() 现有的.发生这种情况是因为如果 Hibernate 从 DB 加载实体(及其集合),它会管理"它们,即.跟踪他们的变化.通常,在使用 Hibernate 时,最好不要为集合(列表、集合)创建任何 setter.只创建getter,并清除它返回的集合,即:

  1. Instead of replacing the collection (team.setUserTeamRoles(new HashSet<UserTeamRole>());) you have to clear() the existing one. This happens because if Hibernate loads the entity (and its collections) from DB, it "manages" them, ie. tracks their changes. Generally when using Hibernate it's better not to create any setters for collections (lists, sets). Create only the getter, and clear the collection returned by it, ie:

team.getUserTeamRoles().clear();

另一件事是您错过了孤立删除(即,当从父对象的集合中删除子对象时删除子对象).要启用它,您需要在拥有实体中添加 @OneToMany(orphanRemoval=true).

Another thing is that you miss orphan deletion (ie. delete child object when it's removed from collection in the parent). To enable it, you need to add @OneToMany(orphanRemoval=true) in owning entity.

这篇关于更新父级时休眠@OneToMany 从列表中删除子级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆