database - unidirectional - Hibernate @OneToMany elimina el elemento secundario de la lista cuando se actualiza el documento principal
onetomany joincolumn (1)
Tengo las siguientes entidades:
EQUIPO
@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;
}
}
y
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;
}
}
Ahora, cuando actualizo una entidad de equipo que contiene, por ejemplo Team.userTeamRoles = {UTR1, UTR2} con {UTR1, UTR3}, quiero que se elimine UTR2. Pero la forma en que lo hago ahora, la lista anterior sigue siendo la misma y solo agrega UTR3 a la lista.
Así es como lo hago en este momento:
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);
Pensé que al hacer team.setUserTeamRoles(new HashSet<UserTeamRole>());
la lista se restablecería y, debido a las cascadas, la lista anterior se eliminaría.
Cualquier ayuda es apreciada. Gracias
En lugar de reemplazar la colección (
team.setUserTeamRoles(new HashSet<UserTeamRole>());
) debeclear()
la existente. Esto sucede porque si Hibernate carga la entidad (y sus colecciones) de DB, las "administra", es decir. rastrea sus cambios. En general, cuando se utiliza Hibernate, es mejor no crear ningún setter para colecciones (listas, conjuntos). Cree solo el getter y borre la colección devuelta por este, es decir:team.getUserTeamRoles().clear();
Otra cosa es que omita la eliminación de huérfanos (es decir, eliminar objeto hijo cuando se elimina de la colección en el elemento primario). Para habilitarlo, necesita agregar
@OneToMany(orphanRemoval=true)
en la entidad propietaria.