2011-01-11 60 views
2

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

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();删除操作会立即刷到底层数据库,所以我没有真正期待它的帮助。

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

回答

0

您可以从EntityManager接口

清除整个缓存,采用clear()方法或者,如果你知道,所有的交易属于某个帐户,你可以调用EntityManagerrefresh(Object entity)Account对象。

0

以后的问题是在代码中, 仍然在同一个事务 (执行事务这个时候)我 需要遍历所有 存在一些交易的条目中, 的EntityManager仍然给我的 我刚刚删除了 的交易。

刷新模式

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

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

也许如果您使用FlushModeType.COMMIT,则可以作为交易反映的变化仅提交您要执行同一事务中的两个查询&出现的问题。与FlushModeType.AUTO它应该工作正常&它的默认,所以不需要明确提及它。

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

0

首先,你确定批量删除语句是必需的吗?即如果您没有它,您会跨越一些不良的性能阈值。如果你不需要它,那么你可以使用session.delete(e)。否则,如果您使用休眠,如问题中的标记所示,则可以使用session.evict(e)手动从会话中删除实体。您可以使用建议的代码here进入休眠会话。

希望有所帮助。