Reputation: 53
I have a simple parent / children obj bi-directional relationship defined. I want to perform cascade delete so that when parent is removed, all the children would be removed as well with one 1 delete call from parent. Here are my pojo class declaration:
@Entity
@Table(name = "Agent_Assignment", schema = "xxx", catalog = "AAA")
public class AgentAssignment {
private Set<AgentAssignmentAttr> attributes = new HashSet<AgentAssignmentAttr>();
@OneToMany( fetch=FetchType.EAGER, cascade=CascadeType.ALL, orphanRemoval=true )
@JoinColumn(name="Agent_Assignment_GUID")
public Set<AgentAssignmentAttr> getAttributes() {
return attributes;
}
public void setAttributes(Set<AgentAssignmentAttr> attributes) {
this.attributes = attributes;
}
}
@Entity
@Table(name = "Agent_Assignment_Attr", schema = "xxx", catalog = "AAA")
public class AgentAssignmentAttr {
private AgentAssignment asgnmnt = null;
@ManyToOne( fetch=FetchType.EAGER )
@JoinColumn(name="Agent_Assignment_GUID", insertable=false, updatable=false)
public AgentAssignment getAssignment() {
return asgnmnt;
}
public void setAssignment(AgentAssignment assignment) {
this.asgnmnt = assignment;
}
}
And the code to delete is:
AgentAssignment assgnmnt = (...some HQL query to returns the AgentAssignment obj)
getSession().delete(assgnmnt);
When execute the above delete call, it throws exception:
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
Basically, when log at the Hibernate log's SQL being executed, it doesn't call "update" on Agent_Assignment_Attr table's row it supposed to delete, but instead call "update" on the row to set the foreign key column "Agent_Assignement_GUID" to null, as shown below:
/* delete one-to-many com.cs.mytime.acr.model.AgentAssignment.attributes */ update
MyTime.dbo.Agent_Assignment_Attr
set
Agent_Assignment_GUID=null
where
Agent_Assignment_GUID=?
2014/08/22 16:31:10.430 [TRACE] <http-bio-8080-exec-5> (BasicBinder.bind:81) - binding parameter [1] as [VARCHAR] - [CA91A4F3-6F7E-4188-B299-8E9DF17F0385]
Appreciate anybody to help to see if there's something I have missed and the right solution. Thanks.
Upvotes: 4
Views: 3958
Reputation: 11070
In order to get a delete instead of an update I had to use this approach:
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
@JoinColumn(name = "PARENT_ID", referencedColumnName = "PARENT_ID", updatable = false)
private List<ChildEntity> children;
Upvotes: 0
Reputation: 692281
Your mapping is wrong. A bidirectional assocition must only define how the association is mapped once. What you have there is two distinct, unrelated associations that happen to use the same column. The mapping should be
@OneToMany(mappedBy="assignment", fetch=FetchType.EAGER, cascade=CascadeType.ALL, orphanRemoval=true )
public Set<AgentAssignmentAttr> getAttributes() {
return attributes;
}
where mappedBy
says: "I'm the inverse side of the bidirectional association defined and mapped on AgentAssignmentAttr.assignment
, and
@ManyToOne( fetch=FetchType.EAGER )
@JoinColumn(name="Agent_Assignment_GUID")
public AgentAssignment getAssignment() {
return asgnmnt;
}
Upvotes: 1