开发者

Make JPA aware of database changes

开发者 https://www.devze.com 2023-02-04 15:06 出处:网络
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 n开发者_P

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 n开发者_Python百科eed 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.


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.


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号