【问题标题】:JPA cannot delete entities with a onotomany relation and a cascatype allJPA 无法删除具有 onotomany 关系和 cascatype all 的实体
【发布时间】:2013-04-26 01:31:00
【问题描述】:

我正在尝试删除一个实体,但是当我使用实体管理器时我没有错误,但数据仍在数据库中,我正在使用全部级联,与此无关,我将其父引用删除为

Parent parent = child.getParent();
parent.getChildren().remove(child);
entityManager.remove(child);
entityManager.merge(parent);

有人知道怎么做吗?

【问题讨论】:

  • 检查您是否处于事务中,并且 entityManager.flush() 将语句推送到数据库。如果你在一个事务中,在它提交之前什么都不会发生(或者你调用flush),而如果你不在一个事务中,什么都不会发生——尽管flush应该给你一个异常。

标签: java jpa entity one-to-many entitymanager


【解决方案1】:

这可能有几个原因:

您没有从孩子中删除父引用 - child.setParent(null); 这很重要,因为父 id 可能存储在子表中。

当您调用merge 时,尚未提交删除。这应该不是问题,但如果第一个想法没有帮助,我会尝试将删除和合并放在单独的事务中。

我假设您只在父级上使用CascadeType.ALL。

【讨论】:

    【解决方案2】:

    根据克里斯的评论进行编辑,因为它确实根本不清楚。

    第一,你必须明白一个实体实例可以有很多状态。 http://openjpa.apache.org/builds/1.2.3/apache-openjpa/docs/jpa_overview_em_lifecycle.html

    Merge 用于将实体附加到当前 entityManager。一旦它被管理,当 EntityManager 被刷新时,您将对实体进行的所有修改都将保存在数据库中。这通常发生在当前事务结束时(或者当您手动调用 flush 或 entityManager 估计有必要时)。

    如果您的实体已在当前事务中从数据库中检索到,则无需调用合并,因为它们已被管理。

    假设这个

    你只需要打电话

    entityManager.remove(child);
    

    或者

    parent.getChildren().remove(child);
    

    如果您已对关系(在父级中)配置了孤立删除。

    这将自动刷新到数据库当当前事务将被刷新而不是在方法调用时。

    否则,您可以使用 entityManager.flush() 强制刷新,但这是一种不好的做法。无论如何,在事务提交/关闭之前,您不会看到数据库中的更改。

    如果您想使用entityManager.remove(child) 删除子实体,如果您的父实例当前处于托管状态(意味着它实际上存在你的父母在内存中,因为你已经检索了它,或者因为你调用了 child.getParent() 或者因为它在你检索孩子时被急切地加载。)

    【讨论】:

    • 您应该维护双向关系的双方,否则实体与数据库中的内容不同步。如果与已删除实体的关系被标记为级联持续存在且未清理,它还会冒无意中复活实体的风险。
    • @Chris 感谢整改
    猜你喜欢
    • 2016-04-21
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 2011-07-17
    • 2013-05-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多