Информировать JPA об изменениях в базе данных - PullRequest
2 голосов
/ 11 января 2011

У меня есть две сущности: транзакция и запись.Транзакция имеет некоторые собственные данные и список из одной или нескольких записей, который состоит из дебета и суммы кредита.В одной части приложения мне нужно было удалить почти все из них, и я обнаружил, что 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 ();удаленные данные немедленно сбрасываются в основную базу данных, поэтому я не ожидал, что это поможет.

Цените все указатели, подсказки и ответы.

Ответы [ 3 ]

0 голосов
/ 12 января 2011

Проблема позже в коде, все еще в той же транзакции (выполнение транзакции на этот раз) я необходимо пройти все записи, которые существует на некоторых транзакциях, EntityManager все еще дает мне транзакции, которые я только недавно удален.

Режим промывки

  • AUTO - поведение по умолчанию. Все обновления, которые вы внесли в свою транзакцию, сбрасываются, чтобы ваш запрос воспринял эти изменения.

  • COMMIT означает, что изменения сбрасываются только при фиксации транзакции, а не перед каким-либо запросом.

Возможно, если вы используете FlushModeType.COMMIT, проблема может возникнуть, так как изменения отражаются только на фиксации транзакции и вы выполняете два запроса в одной транзакции. С FlushModeType.AUTO он должен работать нормально и по умолчанию, поэтому нет необходимости упоминать об этом явно.

Если проблема не устранена, попробуйте выполнить транзакцию после первого запроса.

0 голосов
/ 02 февраля 2011

Прежде всего, вы уверены, что необходим оператор массового удаления?то есть вы переступите какой-то нежелательный порог производительности, если у вас его нет.Если вам это не нужно, вы можете использовать session.delete(e).

В противном случае, если вы используете спящий режим, как указывает тэг в вашем вопросе, вы можете использовать session.evict(e) для удаления сущностей из сеанса вручную.Вы можете попасть в сеанс гибернации, используя код, рекомендованный здесь .

Надеюсь, это поможет.

0 голосов
/ 11 января 2011

Вы можете очистить весь кэш, используя метод clear() из интерфейса EntityManager

Или, если вы знаете, что все транзакции принадлежат определенной учетной записи, вы можете позвонитьrefresh(Object entity) в EntityManager для объекта Account.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...