【问题标题】:Hibernate @OneToMany remove child from list when updating parentHibernate @OneToMany 在更新父级时从列表中删除子级
【发布时间】:2013-01-19 03:27:22
【问题描述】:

我有以下实体:

团队

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

现在,当使用 {UTR1, UTR3} 更新包含 Team.userTeamRoles = {UTR1, UTR2} 的团队实体时,我希望删除 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&lt;UserTeamRole&gt;());,列表将被重置,并且由于级联,先前的列表将被删除。

感谢任何帮助。谢谢

【问题讨论】:

标签: database hibernate jpa associations one-to-many


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

    team.getUserTeamRoles().clear();

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

【讨论】:

  • @Adam Dyga Hibernate noob here,你能解释一下为什么最好不要为集合创建任何 setter 吗?
  • @Jonny 尝试将实体中的集合替换为新集合(例如 new ArrayList()),然后查看保存时会发生什么;)
  • 感谢您的明确答复。但是,如果我使用 new 关键字重新创建父对象并手动插入 ID 到它(即对象不是由 Hibernate“管理”并且它处于瞬态状态),我可以做同样的技巧吗?
  • @MyTitle 你为什么想做这样的事情?
猜你喜欢
  • 1970-01-01
  • 2014-09-02
  • 2013-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-16
  • 1970-01-01
  • 2013-01-31
相关资源
最近更新 更多