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, содержащей, например, Team.userTeamRoles = {UTR1, UTR2} с {UTR1, UTR3}, я хочу, чтобы 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>()); список будет обнулен и из-за каскадов предыдущий список будет удален.

любая помощь приветствуется. Спасибо

1 ответов


  1. вместо замены коллекции (team.setUserTeamRoles(new HashSet<UserTeamRole>());) нужно clear() существующую. Это происходит потому, что если Hibernate загружает объект (и его коллекции) из БД, он "управляет" ими, т. е. отслеживает их изменения. Обычно при использовании Hibernate это лучше не для создания любых сеттеров для коллекций (списков, наборов). Создайте только геттер и очистите возвращаемую им коллекцию, т. е.:

    team.getUserTeamRoles().clear();

  2. другой дело в том, что вы пропускаете сиротское удаление (т. е. удалить дочерний объект, когда он удаляется из коллекции в Родительском). Чтобы включить его, вам нужно добавить @OneToMany(orphanRemoval=true) во владении лица.