【问题标题】:Make JPA aware of database changes让 JPA 了解数据库更改
【发布时间】:2011-06-07 02:18:39
【问题描述】:

我有两个实体,交易和入口。交易有一些自己的数据和一个或多个条目的列表,其中包括借方和贷方金额。在应用程序的一部分中,我需要删除几乎所有这些,并发现 JPQL 在这种情况下是最简单和最快的。

我执行这段代码:

entityManager.createQuery(
                "DELETE FROM Entry e WHERE e IN (:entries)").
                setParameter("entries", new ArrayList<Entry>(
                entriesToRemove)).executeUpdate();
entityManager.createQuery(
                "DELETE FROM Transaction e WHERE e IN (:transactions)").
                setParameter("transactions", new ArrayList<Transaction>(
                transactions)).executeUpdate();

问题出在代码后面,仍然在同一个事务中(这次是执行事务)我需要遍历某些事务上存在的所有条目,EntityManager 仍然给我刚刚删除的事务。

我怀疑应该有一种方法来处理此事件,在我的示例中,我只执行了两个删除 JPQL,但我也可以调用外部服务或其他影响数据库的外部服务。无论如何,我需要确保 EntityManager 的缓存仍然有效,因为它现在仍然包含已删除的对象。

我已经尝试过 entityManager.flush();在这些删除后没有成功。因为我使用 executeUpdate();删除会立即刷新到底层数据库,所以我真的没想到它会有所帮助。

欣赏任何和所有的指针、提示和答案。

【问题讨论】:

    标签: hibernate jpa jpql


    【解决方案1】:

    您可以使用EntityManager 接口中的clear() 方法清除整个缓存

    或者,如果您知道所有交易都属于某个账户,您可以在EntityManager 中为Account 对象调用refresh(Object entity)

    【讨论】:

      【解决方案2】:

      问题出在代码后面, 仍在同一事务中 (本次执行交易)我 需要遍历所有的条目 存在于某些交易中, EntityManager 仍然给我 我最近的交易 删除。

      冲洗模式

      • AUTO 是默认行为。您在事务中所做的任何更新都会被刷新,以便您的查询将获取这些更改。

      • COMMIT 表示仅在事务提交时刷新更改,而不是在任何查询之前。

      如果您使用FlushModeType.COMMIT,则可能会出现问题,因为更改仅反映在事务提交上,并且您在同一事务中执行两个查询。使用FlushModeType.AUTO,它应该可以正常工作并且是默认设置,因此无需明确提及。

      如果问题仍然存在,那么您可以在第一次查询后尝试提交事务。

      【讨论】:

        【解决方案3】:

        首先,您确定需要批量删除语句吗?即,如果您没有它,您将跨越一些不良的性能阈值。如果您不需要它,那么您可以使用session.delete(e)

        否则,如果您使用休眠,正如您问题中的标签所示,您可以使用session.evict(e) 手动从会话中删除实体。您可以使用推荐的代码here 进入休眠会话。

        希望对您有所帮助。

        【讨论】:

          猜你喜欢
          • 2013-05-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-10
          • 1970-01-01
          相关资源
          最近更新 更多