我有@OneToOne关系的以下实体:
@Entity
public static class EntityChild extends BaseEntity {
//Id from superclass
}
@Entity
public static class EntityParent extends BaseEntity {
//Id from superclass
@OneToOne(cascade = ALL)
private EntityChild child;
//child getter/setter
}
现在,以下测试未通过:
EntityParent parent = new EntityParent();
em.persist(parent);
em.flush();
EntityChild child = new EntityChild();
parent.setChild(child);
em.persist(parent);
em.flush();
em.remove(parent.getChild());
em.flush();
它在最后一行抛出异常,使用flush()。例外是javax.persistence.EntityNotFoundException: deleted entity passed to persist: [my.package.EntityChild#<null>]
为什么我不能删除这个实体?
答案 0 :(得分:5)
您需要首先删除父级和子级之间的关联,否则Hibernate会因cascade = ALL
而尝试再次保留该子级:
EntityChild c = parent.getChild();
parent.setChild(null);
em.remove(c);
em.flush();
<强>更新强>
以下是与此行为相关的JPA specification的摘录。由于[{1}}期间[1]和[2]之间的冲突引发了异常(虽然我找不到它指定的位置):
应用于实体X的 flush 操作的语义如下:
如果X是托管实体,则会将其同步到数据库。
对于来自X的关系引用的所有实体Y,如果与Y的关系已经过 使用
flush()
元素值cascade
或cascade=PERSIST
进行注释,将持久操作应用于Y.对于由X的关系引用的任何实体Y,其中与Y的关系具有 未使用
cascade=ALL
元素值cascade
或cascade=PERSIST
进行注释:
如果Y是新的或已删除,则会抛出
cascade= ALL
通过刷新操作(以及标记为回滚的事务)或事务 提交将失败。如果分离Y,则语义取决于关系的所有权。 如果X拥有该关系,则对该关系的任何更改都将同步 与数据库;否则,如果Y拥有关系,那么行为 未定义。
如果X是已删除的实体,则会从数据库中删除它。没有级联选项是相关的。 &lt; --------------- [1]
持久性的语义 操作,应用于实体X 如下:
如果X是新实体,那么 变得有管理。实体X将是 在或之前进入数据库 事务提交或由于 冲洗操作。
如果X是a 预先存在的管理实体,它是 被持久化操作忽略。 但是,持续的操作是 级联到X引用的实体, 如果从X到这些的关系 其他实体用。注释
IllegalStateException
或cascade=PERSIST
注释元素值或指定 使用等效的XML描述符 元件。如果X是已移除的实体, 它变得有管理。 &lt; --------------- [2]
如果X是a 分离的对象, 可能会抛出
cascade=ALL
当调用持久化操作时, 或EntityExistsException
或 另一个EntityExistsException
可能是 在刷新或提交时抛出。有关 a引用的所有实体Y. 来自X的关系,如果是 与Y的关系已被注释 具有级联元素值
PersistenceException
或cascade=PERSIST
,{。}} 持久操作适用于Y。