让 JPA 了解数据库更改

发布于 2024-10-11 06:22:45 字数 907 浏览 2 评论 0原文

我有两个实体,交易和条目。交易有一些自己的数据和一个或多个条目的列表,其中包含借方和贷方金额。在应用程序的一部分中,我需要删除几乎所有这些内容,并发现 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();删除会立即刷新到底层数据库,所以我并没有真正期望它有帮助。

感谢所有的指点、提示和答案。

I have two Entities, Transaction and Entry. Transaction has some own data and a list of one or several Entries which consists of a debit and a credit amount. In one part of the application I need to remove almost all of these and found that JPQL is easiest and fastest in this instance.

I execute this code:

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();

The problem is later in the code, still in the same transaction (execution transaction this time) I need to traverse all the entries that exists on some transactions, the EntityManager still gives me the transactions that I just recently removed.

I suspect that there should be a way of handling this event, in my example here I just execute two delete JPQLs but I could also have called an external service or something else outside that affected the database. In any case I need to make sure that the EntityManager's cache is still valid, because as it is now it still contains the deleted objects.

I have tried with entityManager.flush(); after these deletes to no success. Since I use executeUpdate(); the deletes are flushed immediately to the underlaying database so I didn't really expect it to help.

Appreciate any and all pointers, hints and answers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

挖鼻大婶 2024-10-18 06:22:45

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

或者,如果您知道所有交易都属于某个帐户,则可以调用 刷新(对象实体) 位于 Account 对象的 EntityManager 中。

You can clear the whole cache, using the clear() method from EntityManager interface

Or, if you know that all transactions belongs to a certain account, you can call refresh(Object entity) in the EntityManager for the Account object.

傲影 2024-10-18 06:22:45

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

冲洗模式

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

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

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

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

The problem is later in the code,
still in the same transaction
(execution transaction this time) I
need to traverse all the entries that
exists on some transactions, the
EntityManager still gives me the
transactions that I just recently
removed.

Flush Mode

  • AUTO is the default behavior. Any updates you've made within your transaction are flushed so that your query will pick up these changes.

  • COMMIT means that changes are flushed only when the transaction commits, not before any query.

Probably if you are using FlushModeType.COMMIT, then the problem can arise as the changes are reflected on transaction commit only & you are executing two queries within same transaction. With FlushModeType.AUTO it should work fine & its default so no need to mention it explicitly.

If still problem exists, then you can try committing the transaction after first query.

枕头说它不想醒 2024-10-18 06:22:45

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

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

希望有帮助。

First of all, are you sure that the bulk delete statement is necessary? i.e. you will cross some undesirable performance threshold if you don't have it. If you don't need it then you can use session.delete(e).

Otherwise, if you're using hibernate, as the tag in your question indicates, you can use session.evict(e) to remove entities from the session manually. You can get to the hibernate session by using the code recommended here.

Hope that helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文