2016-02-27 3 views
1

Я использую JPA для сохранения данных.Проблема с синхронизацией запроса SQL-запросов в JPA

Я не могу объяснить поведение в своей программе.

У меня есть объект A который имеет другую сущность B как его member.In мой код я создаю новый экземпляр A и установить экземпляр B (сгружено из базы данных) в A, а потом сохранить A с помощью EntityManager. Я использую транзакцию, управляемую контейнером, поэтому все транзакции должны совершать в конце метода.

В том же методе, после сохранения A, я пытаюсь получить объект класса C. C, как A, имеет B в качестве своего члена. Я использую запрос JQPL для извлечения C для идентификатора экземпляра B, связанного с экземпляром A.

Проблема заключается в том, что при извлечении C JPA также выполняет SQL-запрос для сохранения A. Я ожидаю, что это произойдет в конце транзакции (т. Е. Когда метод закончится). Но это происходит, когда я пытаюсь забрать C. Если я не получаю C, тогда SQL-запрос для сохранения A выдается, когда метод заканчивается.

В чем причина такого поведения?

ответ

0

Поставщик JPA должен очистить контекст персистентности до выполнения запроса, если есть вероятность, что результаты запроса не будут соответствовать текущему состоянию постоянного состояния.

Вы можете установить flush mode на COMMIT для желаемых (или всех) сеансов. Просто имейте в виду, чтобы вручную очистить сеанс, если запрос зависит от состояния контекста грязного состояния. Режим сброса по умолчанию - AUTO, что означает, что контекст персистентности может быть очищен до выполнения запроса.

+0

Хм .... это очень правдоподобная точка. Благодаря тонну. Кстати, как вы узнаете каждую мелочь поведения JPA. Я постоянно читаю и экспериментирую, но все же время от времени такие проблемы продолжают возникать, что мне трудно объяснить. Любой хороший ресурс? – Mandroid

+0

Добро пожаловать. Нет ни одного источника обучения, охватывающего все. Книги, форумы, статьи, эксперименты, глубокий дайвинг исходный код ... –

+0

Вы должны прочитать спецификацию https://jcp.org/en/jsr/detail?id=338 ИМХО это очень ясно. BTW мой ответ ниже правильный на всякий случай ... –

0

Причина - уровень изоляции базы данных. По умолчанию используется read_commited. Подробнее об уровнях изоляции здесь: https://en.wikipedia.org/wiki/Isolation_%28database_systems%29#Read_committed

Так чтобы не нарушить эту изоляцию JPA должен выполнить все SQL-операторы в буфере, что все данные в транзакции достигший базы данных.

 Смежные вопросы

  • Нет связанных вопросов^_^