无法删除作为@OneToOne关系目标的实体

时间:2011-01-20 14:40:13

标签: 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
}

现在,以下测试未通过:

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>]

为什么我不能删除这个实体?

1 个答案:

答案 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()元素值cascadecascade=PERSIST进行注释,将持久操作应用于Y.

    •   
    • 对于由X的关系引用的任何实体Y,其中与Y的关系具有   未使用cascade=ALL元素值cascadecascade=PERSIST进行注释:

           
          
      • 如果Y是新的或已删除,则会抛出cascade= ALL   通过刷新操作(以及标记为回滚的事务)或事务   提交将失败。

      •   
      • 如果分离Y,则语义取决于关系的所有权。   如果X拥有该关系,则对该关系的任何更改都将同步   与数据库;否则,如果Y拥有关系,那么行为   未定义。

      •   
    •   
  •   
  • 如果X是已删除的实体,则会从数据库中删除它。没有级联选项是相关的。 &lt; --------------- [1]

  •   

  

持久性的语义   操作,应用于实体X   如下:

     
      
  • 如果X是新实体,那么   变得有管理。实体X将是   在或之前进入数据库   事务提交或由于   冲洗操作。

  •   
  • 如果X是a   预先存在的管理实体,它是   被持久化操作忽略。   但是,持续的操作是   级联到X引用的实体,   如果从X到这些的关系   其他实体用。注释   IllegalStateExceptioncascade=PERSIST   注释元素值或指定   使用等效的XML描述符   元件。

  •   
  • 如果X是已移除的实体,   它变得有管理。 &lt; --------------- [2]

  •   
  • 如果X是a   分离的对象,   可能会抛出cascade=ALL   当调用持久化操作时,   或EntityExistsException或   另一个EntityExistsException可能是   在刷新或提交时抛出。

  •   
  • 有关   a引用的所有实体Y.   来自X的关系,如果是   与Y的关系已被注释   具有级联元素值   PersistenceExceptioncascade=PERSIST,{。}}   持久操作适用于Y。

  •