Team
and TeamMember
are in ManyToMany relationship. When I tried to delete team like this:
public void deleteTeam(int id) {
Team team = (Team) getCurrentSession().get(Team.class, id);
getCurrentSession().delete(team);
}
It gave:
org.springframework.dao.InvalidDataAccessApiUsageException: deleted object would be re-saved by cascade (remove deleted object from associations): [com.sprhib.model.Team#1];
nested exception is org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [com.sprhib.model.Team#1]
ThenI tried to delete all teams from team member entities that are holding THE TEAM I need to delete:
public void deleteTeam(int id) {
Team team = getTeam(id);
if(team != null){
for(TeamMember tm: team.getTeamMembers()){
for(Team t: tm.getTeams()){
if(t.getId() == team.getId()){
tm.getTeams().remove(t);
}
}
}
getCurrentSession().delete(team);
}
}
But the same error stays. First of all I expected Hibernate to manage all related entities in ManyToMany relation accordingly since they have annotations. But it refuses to work. WTF?
Team
@Entity
@Table(name="teams")
public class Team {
private int id;
private String name;
private int rating;
private Set<TeamMember> teamMembers;
private Organization organization;
@Id
@NotNull
@GeneratedValue(strategy = GenerationType.AUTO)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Length(max = 45)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@NotNull
@Range(min = 0,max = 10)
public int getRating() {
return rating;
}
public void setRating(int rating) {
this.rating = rating;
}
@NotNull
@ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE})
@JoinColumn(name = "FK_Organization_id", nullable = false)
public Organization getOrganization() {
return organization;
}
public void setOrganization(Organization organization) {
this.organization = organization;
}
@ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
@JoinTable(name = "team_member", joinColumns =
@JoinColumn(name = "FK_Team_id", referencedColumnName= "id"),
inverseJoinColumns = @JoinColumn(name = "FK_Member_id", referencedColumnName = "id")
)
public Set<TeamMember> getTeamMembers() {
return teamMembers;
}
public void setTeamMembers(Set<TeamMember> teamMembers) {
this.teamMembers = teamMembers;
}
}
TeamMember
@Entity
@Table(name="member")
public class TeamMember {
private int id;
private String name;
private Set<Team> teams;
@Id
@NotNull
@GeneratedValue(strategy = GenerationType.AUTO)
public int getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@NotEmpty
@Length(max=100)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@NotNull
@ManyToMany(fetch = FetchType.EAGER, mappedBy = "teamMembers", cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.REMOVE}) // cascade!!!
public Set<Team> getTeams(){
return teams;
}
public void setTeams(Set<Team> teams) {
this.teams = teams;
}
}
REMOVE should not be used with @ManyToMany from JPA 2.0 spec.
The relationship modeling annotation constrains the use of the cascade=REMOVE specification. The cascade=REMOVE specification should only be applied to associations that are specified as OneToOne or OneToMany. Applications that apply cascade=REMOVE to other associations are not portable.
There is vendor extension @OnDelete in Hibernate:
@OnDelete(action=OnDeleteAction.CASCADE)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.