我有2个EJB 3实体Bean:
@Entity
public class Organisation
{
@Id
@Column(length = 64)
private String guid;
private String name;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
@JoinColumn(name = "home_unit_fk", nullable = true)
private Unit homeUnit;
}
@Entity
public class Unit
{
@Id
@Column(length = 64)
private String guid;
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "organisation_fk", nullable = false)
private Organisation organisation;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_unit_fk", nullable = true)
private Unit parentUnit;
@OneToMany(mappedBy = "parentUnit", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
@OrderBy("shortName")
@OptimisticLock(excluded = true)
private Set<Unit> childUnits;
}
如果我使用标准Dao对组织进行删除:
public int deleteByGuid(final String guid)
{
final Query query = entityManager.createQuery("delete from " + getPersistentClass().getName() + " where guid = :guid");
query.setParameter("guid", guid);
return query.executeUpdate();
}
但我得到以下例外:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:无法删除或更新父行:外键约束失败(config
。unit
,CONSTRAINT FK27D184F5D4393D
FOREIGN KEY( organisation_fk
)参考organisation
(guid
))
我不明白。我究竟做错了什么? JPA / Hibernate不应该在同一个事务中对Unit和Organization进行删除吗?
答案 0 :(得分:2)
批量删除查询不会将对象加载到内存中,并且会绕过关联中指定的任何级联。
我会将您的删除方法编码为:
public int deleteByGuid(final String guid){
Organization org = entityManager.find(Organization.class, guid);
entityManager.remove(org);
}
如果使用Query进行批量更新,则会直接将操作委派给数据库。如果要删除子对象,则必须在“数据库”级别设置DELETE CASCADE触发器。
通过加载对象并将其删除,Hibernate将在“对象”级别触发级联。