2013-02-04 24 views
27

tôi có các đối tượng sau:Hibernate @OneToMany loại bỏ con ra khỏi danh sách khi cập nhật mẹ

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

}

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

Bây giờ , khi cập nhật thực thể Team có chứa Team.userTeamRoles = {UTR1, UTR2} với {UTR1, UTR3}, tôi muốn xóa UTR2. Nhưng cách tôi làm điều đó bây giờ, danh sách cũ vẫn giữ nguyên và nó chỉ thêm UTR3 vào danh sách.

Đây là cách tôi làm điều đó vào lúc này:

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

Tôi nghĩ rằng bằng cách làm team.setUserTeamRoles(new HashSet<UserTeamRole>()); danh sách sẽ được thiết lập lại và vì sự thác các danh sách trước đó sẽ bị xóa.

Mọi trợ giúp đều được đánh giá cao. Cảm ơn bạn

+0

tôi nghĩ là cùng một vấn đề ở đây: http://stackoverflow.com/questions/2011519/jpa-onetomany-not-deleting-child kiểm tra xem nó ra! –

Trả lời

82
  1. Thay vì thay thế các bộ sưu tập (team.setUserTeamRoles(new HashSet<UserTeamRole>());) bạn phải clear() sự hiện có. Điều này xảy ra vì nếu Hibernate nạp thực thể (và các bộ sưu tập của nó) từ DB, nó "quản lý" chúng, nghĩa là. theo dõi thay đổi của họ. Nói chung khi sử dụng Hibernate thì tốt hơn là không phải để tạo bất kỳ bộ định vị nào cho bộ sưu tập (danh sách, bộ). Tạo chỉ getter, và rõ ràng các bộ sưu tập được trả về bởi nó, ví dụ:

    team.getUserTeamRoles().clear();

  2. Một điều nữa là bạn bỏ lỡ xóa mồ côi (tức là xóa đối tượng trẻ khi nó ra khỏi bộ sưu tập ở công ty mẹ.). Để kích hoạt nó, bạn cần phải thêm @OneToMany(orphanRemoval=true) trong việc sở hữu thực thể.

+2

Vâng, rõ ràng + orphanRemoval đã làm các trick. Cảm ơn rất nhiều! – AndaP

+0

@Adam Dyga Hibernate noob ở đây, bạn có thể giải thích thêm về lý do tại sao tốt hơn là không tạo bất kỳ người định cư nào cho các bộ sưu tập? – Jonathan

+0

@Jonny cố gắng thay thế một bộ sưu tập trong thực thể bằng một thực thể mới (ví dụ: ArrayList mới()) và xem điều gì xảy ra khi lưu;) –

Các vấn đề liên quan