Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have the following entities:

TEAM

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

}

and

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

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.

This is how I do it at the moment:

 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);

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.

Any help is appreciated. Thank you

share|improve this question
 
I think is the same problem here: stackoverflow.com/questions/2011519/… check it out! –  Diogo Moreira Feb 4 at 12:20

1 Answer

up vote 2 down vote accepted
  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();

  2. 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.

share|improve this answer
 
Yep, the clear + orphanRemoval did the trick. Thanks a lot! –  AndaP Feb 4 at 12:43
 
@Adam Dyga Hibernate noob here, could you explain more on why it's better not to create any setters for collections? –  Jonny Oct 17 at 23:43
 
@Jonny try to replace a collection in an entity with an new one (eg. new ArrayList()) and see what happens on save ;) –  Adam Dyga Oct 18 at 10:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.