amo*_*fis 4 java hibernate jpa
我有@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
}
Run Code Online (Sandbox Code Playgroud)
现在以下测试没有通过:
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();
Run Code Online (Sandbox Code Playgroud)
它使用flush()在最后一行抛出异常.例外是javax.persistence.EntityNotFoundException: deleted entity passed to persist: [my.package.EntityChild#<null>]
为什么我不能删除这个实体?
您需要首先删除父级和子级之间的关联,否则Hibernate会尝试再次保留该子级,原因cascade = ALL如下:
EntityChild c = parent.getChild();
parent.setChild(null);
em.remove(c);
em.flush();
Run Code Online (Sandbox Code Playgroud)
更新:
以下是与此行为相关的JPA规范的摘录.由于[1]和[2]之间的冲突而引发异常flush()(尽管我找不到它指定的位置):
应用于实体X 的刷新操作的语义如下:
如果X是托管实体,则会将其同步到数据库.
通过从X的关系中引用的所有实体Y,如果Y的关系已经被注释与所述
cascade元素值cascade=PERSIST或cascade=ALL,persist操作被施加到Y.对于由X的关系引用的任何实体Y,其中与Y的关系未使用
cascade元素值注释cascade=PERSIST或cascade= ALL:
如果Y是新的或被删除,
IllegalStateException则刷新操作(以及标记为回滚的事务)将抛出一个或者事务提交将失败.如果分离Y,则语义取决于关系的所有权.如果X拥有该关系,则对该关系的任何更改都将与数据库同步; 否则,如果Y拥有关系,则行为未定义.
如果X是已删除的实体,则会从数据库中删除它.没有级联选项是相关的.<--------------- [1]
应用于实体X 的持久化操作的语义如下:
如果X是一个新实体,它就会被管理.实体X将在事务提交时或之前或作为刷新操作的结果输入数据库.
如果X是预先存在的托管实体,则persist操作会忽略它.但是,如果从X到这些其他实体的关系使用
cascade=PERSIST或cascade=ALL注释元素值注释或使用等效的XML描述符元素指定,则持久化操作将级联到X引用的实体 .如果X是已删除的实体,则它将被管理.<--------------- [2]
如果X是一个分离的对象,则
EntityExistsException可以在调用持久化操作时抛出,或者可以在刷新或提交时抛出该EntityExistsException另一个或另一个PersistenceException.通过从X的关系中引用的所有实体Y,如果Y的关系已经被注释与级联元件值
cascade=PERSIST或cascade=ALL,persist操作被施加到Y.