Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 静默忽略删除()_Java_Hibernate_Jpa_Jpa 2.0 - Fatal编程技术网

Java 静默忽略删除()

Java 静默忽略删除(),java,hibernate,jpa,jpa-2.0,Java,Hibernate,Jpa,Jpa 2.0,实体A引用(多对一)实体B,反向引用(映射)从B到A。也有反向引用A到C和反向引用C到A。 当我发布entityManager.remove(A)然后刷新()时,“delete”不会被删除!但也没有例外。就像根本没有调用remove()一样。为什么会这样? 如果在remove()之前我们从反向引用B.listOfA和C.listOfA中提取A,则会按预期生成“delete” 还请注意,我得出的结论是,孤儿移除并不总是如预期的那样有效。现在我开始怀疑层叠可能工作得很好,但在那之后,实际的层叠移除就

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

还请注意,我得出的结论是,孤儿移除并不总是如预期的那样有效。现在我开始怀疑层叠可能工作得很好,但在那之后,实际的层叠移除就像我在这里描述的那样被“吞没”了。

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

要验证是否确实发生了这种情况,请为
org.hibernate
包启用跟踪日志级别,并搜索以下日志条目:

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

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

<property name="hibernate.show_sql" value="true"></property>
以等效形式:

@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文档继承的初始代码,如上所述)

发件人:

致:

再次重复测试,但这次没有删除Todoitem实例(“多”侧),而是删除Todo实例(“一”侧)

问题解决了。成功

重要提示:

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

将实体映射与删除逻辑一起发布会有所帮助。您可能需要检查您是否正在实体管理器上启动和提交事务。孤立删除应仅适用于私有的实体。如果你的“孤儿”与它有其他关系,那么这些关系就需要取消——这是JPA不能为你做的。如果这些关系中的任何一个具有级联设置,则可能会导致类似这样的问题。在处理JPA的缓存时,删除被其他人引用的对象而不修复这些引用会导致各种各样的问题。然后你必须说A计划删除,但JPA重新考虑了,因为我再次调用了em.persist(A)。但我一点也不叫persist()!我只做了em.remove(A)后跟em.flush()。或者你的意思是说persist(B)和persist(C)无论如何都会发生,因为remove(A)以某种方式接触了B和C(即使我没有显式地修改它们)?好的,我将检查。@MaksimGumerov在刷新时持久化操作是否级联到持久化上下文中存在的所有实体的所有关联。
@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();
}
//    @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();
}