当前位置: 首页 > 知识库问答 >
问题:

静默忽略删除()

勾向文
2023-03-14

有一个实体A引用(多对一)实体B,从B到A有反向(映射到)引用。还有一个引用A到C,反向引用C到A。当我发出entitymanager . remove(A)then flush()时,没有生成“delete ”!但是也没有例外。就像根本没有调用remove()一样。为什么会这样?如果在remove()之前我们从反向引用B.listOfA和C.listOfA中提取A,那么“delete”就像预期的那样生成了。

还要注意我的另一个问题,我得出结论,孤儿移除并不总是像预期的那样工作。现在我开始怀疑级联可能工作得很好,但是在实际级联移除之后,就像我在这里描述的那样被“吞噬”了。

共有2个答案

丌官翰采
2023-03-14

我遇到了这个问题。即使启用了show_sql:

<property name="hibernate.show_sql" value="true"></property>

没有输出,删除命令被静默忽略。

这个问题是围绕着一个一对一的关系,其中:todo 1 - * todoitem

环境是:-JSF-wildly 18(JPA默认实现- Hibernate) - PostgreSQL 10

尝试删除任何一侧的实例都会以静默方式失败,服务器输出上没有相应的“delete”命令,也没有任何类型的异常消息。

溶液

首先,我将Wildfly18/JBoss留档示例中建议的多方代码从:

//    @Override
//    public void delete(Todoitem todoitem) {
//        if (todoitem == null) {
//            return;
//        }
//        if (!emPg.contains(todoitem)) {
//            todoitem = emPg.merge(todoitem);
//        }
//        emPg.remove(todoitem);
//        emPg.flush();
//        emPg.clear();
//    }

等效形式:

@Override
public void delete(Todoitem todoitem) {
    if (todoitem == null) {
        return;
    }
    Todoitem ti = emPg.find(Todoitem.class, todoitem.getId());
    if(ti == null) {
        return;
    }
    emPg.remove(ti);
    emPg.flush();
    emPg.clear();
}

不幸的是,我得到了同样的结果——移除无声地忽略了。

然后,我怀疑数据库,因为Hibernate处理自己的密钥。我在实现过程中做了许多测试…为了确保一致性问题,我决定清空数据库,删除关系双方的内容。然后,我使用应用程序的资源(没有SQL命令)创建了新的实体实例和关系,因为除了实体删除之外,一切都运行良好。之后,我使用SQL命令检查数据库关系,以确保一切正常,确实如此。

接下来,我又尝试了一次新的测试,但这次成功了。

然后我恢复代码,取消注释注释的代码,反之亦然,并再次测试。测试再次失败,返回相同的结果——默默地忽略删除。

我再次将代码设置回以前的条件测试以确认结果。确认成功,确认了对两个问题的怀疑,即数据库和代码实现。

由于好消息,我在“一”端重复了相同的内容(下面的代码 - 注释的代码是从 Wildfly 18 文档中继承的初始代码,如上所述)。

从:

//    @Override
//    public void delete(Todo todo) {
//        if(todo == null) {
//            return;
//        }
//        if (!emPg.contains(todo)) {
//            todo = emPg.merge(todo);
//        }
//        //todoitemDao.deleteAll(todo);
//        emPg.remove(todo);
//        emPg.flush();
//    }

自:

@Override
public void delete(Todo todo) {
    if (todo == null) {
        return;
    }
    Todo t = emPg.find(Todo.class, todo.getId());
    if(t == null) {
        return;
    }
    emPg.remove(t);
    emPg.flush();
    emPg.clear();
}

再次重复测试,但这次不是删除Todoitem实例(“多”端),而是删除Todo实例(“一”端)。

问题已解决。成功

重要说明:

直接在数据库上使用SQL语句检查删除测试。有时由于缓存问题或代码实现错误,实例似乎没有被删除,需要分开处理。

淳于涛
2023-03-14

看看这个答案。基本上,JPA规范规定,如果对已删除的实体应用持久化操作,则该实体将再次进行管理。

要验证这是否真的发生,请为org.hibernate包启用跟踪日志级别并搜索日志条目,例如:

un-scheduling entity deletion ...

为避免任何不可预测的行为,建议从加载相同会话/事务的所有其他实体实例中删除对已删除实体的引用。

 类似资料:
  • 问题内容: 有一个实体A引用(多对一)实体B,从B到A的反向(映射)引用。也有从A到C的引用,以及从C到A的反向引用。当我发布entityManager.remove(A)然后flush(),“delete”不会发芽!但也没有例外。就像根本没有调用remove()一样。为什么会这样?如果在remove()之前,我们从反向引用B.listOfA和C.listOfA中提取A,则会按预期生成“删除”。

  • 问题内容: 有一个实体A引用(多对一)实体B,从B到A的反向(映射)引用。也有从A到C的引用,以及从C到A的反向引用。当我发布entityManager.remove(A )然后flush(),“ delete”没有发芽!但也没有例外。就像根本没有调用remove()一样。为什么会这样?如果在remove()之前,我们从反向引用B.listOfA和C.listOfA中提取A,则会按预期生成“删除”

  • 问题内容: 我正在开发一个使用Spring-boot,关系数据库和Elasticsearch的应用程序。 我在代码的2个不同位置使用JSON序列化: 在REST API的响应中。 当代码与Elasticsearch交互时。 我在Elasticsearch中需要一些属性,但我想向应用程序用户隐藏(例如,来自关系数据库的内部ID)。 这是一个实体的例子: 问题 :当对象持久化在Elasticsearc

  • 我使用的是LEFTJOIN,在某些情况下,没有正确的表匹配,因此用空(null)值替换正确的表列。因此,我得到了作为JSON聚合之一。 例如,Postgres 9.3创建输出 如何忽略/删除,以便在右表列为空时我有一个空的 JSON 数组 ?

  • 使用上面的代码片段,是否可以测试忽略调用IgnoreCall的方法。ignoreMethod(Bean)而不需要将整个语句置于布尔条件下? 以下是单元测试代码片段: 注意事项: 重构。即使是糟糕的OO设计,重构也是代价高昂的 方法签名被锁定,除非另一个模式适用于替换 尝试使用Mockito。当和PowerMockito时。在目标静态方法上执行时,存根在运行时调试上不起作用

  • 我已经创建了服务器过滤器,它计算响应大小。它通过创建响应包装器来实现这一点,该包装器将与Apache Commons包装在一起。此外,包装器创建带有包装流的PrintWriter。因此,理论上,无论使用什么方法来创建实际输出,都应该通过CountingOutputStream。 问题是,虽然整个过程对于典型的servlet请求都有效,但对于静态内容却失败了。准确地说,过滤器接收请求,创建响应包装,