Hibernate @OneToMany 在更新父级时从列表中删除子级
Posted
技术标签:
【中文标题】Hibernate @OneToMany 在更新父级时从列表中删除子级【英文标题】:Hibernate @OneToMany remove child from list when updating parent 【发布时间】: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<UserTeamRole>());
,列表将被重置,并且由于级联,先前的列表将被删除。
感谢任何帮助。谢谢
【问题讨论】:
我认为这里有同样的问题:***.com/questions/2011519/… 看看! 【参考方案1】:而不是替换集合 (team.setUserTeamRoles(new HashSet<UserTeamRole>());
),您必须 clear()
现有的集合。发生这种情况是因为如果 Hibernate 从 DB 加载实体(及其集合),它会“管理”它们,即。跟踪他们的变化。通常,在使用 Hibernate 时,最好不要为集合(列表、集合)创建任何 setter。只创建getter,并清除它返回的集合,即:
team.getUserTeamRoles().clear();
另一件事是您错过了孤立删除(即,从父对象的集合中删除子对象时删除子对象)。要启用它,您需要在拥有实体中添加@OneToMany(orphanRemoval=true)
。
【讨论】:
@Adam Dyga Hibernate noob here,你能解释一下为什么最好不要为集合创建任何 setter 吗? @Jonny 尝试将实体中的集合替换为新集合(例如 new ArrayList()),然后查看保存时会发生什么;) 感谢您的明确答复。但是,如果我使用new
关键字重新创建父对象并手动插入 ID 到它(即对象不是由 Hibernate“管理”并且它处于瞬态状态),我可以做同样的技巧吗?
@MyTitle 你为什么想做这样的事情?
请检查我的问题***.com/questions/20057678/…以上是关于Hibernate @OneToMany 在更新父级时从列表中删除子级的主要内容,如果未能解决你的问题,请参考以下文章
Hibernate - 是不是需要在父实体中包含 Set 和 OneToMany 注释?
在 Hibernate/JPA 中保存一个带有子对象的对象 - @OneToMany
Hibernate如何正确删除@OneToMany中的孩子?