我有 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
外键 (organization_fk
) 引用 organization
(guid
))
我不明白。我究竟做错了什么? JPA/Hibernate 不应该在同一事务中对单位和组织执行删除吗?
最佳答案
批量删除查询不会将对象加载到内存中,并且会绕过关联上指定的任何级联。
我会将您的删除方法编码为:
public int deleteByGuid(final String guid){
Organization org = entityManager.find(Organization.class, guid);
entityManager.remove(org);
}
如果使用查询进行批量更新,操作将直接委托(delegate)给数据库。如果您希望删除子对象,则必须在“数据库”级别设置 DELETE CASCADE 触发器。
通过加载对象并删除它,Hibernate 将在“对象”级别触发级联。
关于java - 使用 2 个互锁实体类进行 JPA 删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/807547/