I have three tables Employee, Boss, and Address.
Employee and Boss in this case share the same Address. When I call EntityManager.remove on Employee I get an Integrity Constraint exception because it tries to delete the Address which it can't because Boss still needs it. If no one is using the Address though I would want it to be removed. What should my annotations look like so that I can delete orphans from Address but avoid the integrity constraint?
Exception =
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: DELETE on
table 'Employee' caused a violation of foreign key constraint 'Boss....
Code =
public class Employee {
@OneToMany(targetEntity = Address.class, orphanRemoval = true,cascade = {
CascadeType.ALL
} fetch=FetchType.EAGER)
@JoinTable(name = "Employee_Address")
@XmlElement(required = true)
@OrderColumn
protected List<Address> addresses;
}
public class Boss {
@OneToMany(targetEntity = Address.class, orphanRemoval = true, cascade = {
CascadeType.ALL
}fetch=FetchType.EAGER)
@JoinTable(name = "Boss_Address")
@XmlElement(required = true)
@OrderColumn
protected List<Address> addresses;
}
Address class knows nothing about boss or employee.
Your annotations are correct. When deleting Employee it will attempt to remove it's Addresses.
But if both uses same Address the removal will fail.
Given this scenario use a list of cascades options without CasacadeType.DELETE or CasacadeType.ALL and solve the issue programatically.
Also do not use orphanRemoval in this. See the JPA 2.0 spec, section 2.9:
If an entity that is the target of the relationship is removed from the relationship (by setting the relationship to null or removing the entity from the relationship collection), the remove operation will be applied to the entity being orphaned. The remove operation is applied at the time of the flush operation. The orphanRemoval functionality is intended for entities that are privately "owned" by their parent entity. Portable applications must otherwise not depend upon a specific order of removal, and must not reassign an entity that has been orphaned to another relationship or otherwise attempt to persist it. If the entity being orphaned is a detached, new, or removed entity, the semantics of orphanRemoval do not apply.
If the remove operation is applied to a managed source entity, the remove operation will be cascaded to the relationship target in accordance with the rules of section 3.2.3, (and hence it is not necessary to specify cascade=REMOVE for the relationship).