Почему мои запросы гибернации происходят позже, чем хотелось бы, когда я продолжаю использовать JPA? - PullRequest
2 голосов
/ 17 марта 2012

У меня есть серия сохранений JPA и вызовов установщика (обновлений), которые должны произойти до того, как будут выполнены следующие строки кода, но регистратор показывает, что запросы гибернации, возникающие из-за персистентности, происходят позже, чем следующие строкикода.

Код

myDAO.persist(object1);               //insert 1
myOtherDAO.persist(object2);          //insert 2
object3.setProperty("value");         //update 1

System.out.println ("*****Message 1"); 
doWork();
System.out.println("*****Message 2");

Что показывает регистратор

Hibernate: insert into tableName1...  //insert 1
Hibernate: insert into tableName2...  //insert 2
*****Message 1
ERROR BECAUSE UPDATE DIDNT HAPPEN
*****Message 2
Hibernate: update table3 ...          //update 1 (too late)

Итак, вместо вставки 1 вставьте 2 и обновите 1, все это происходит доСледующие строки кода, кажется, что обновление 1 на самом деле происходит слишком поздно.Может кто-нибудь сказать, почему это происходит со мной и что я сделал, чтобы заслужить это?ложный запрос отправляется сервлету.В сервлете возникает проблема, поскольку он не находит ожидаемое состояние в базе данных.Является ли сервлет вне транзакции и эффективно ли он «обходит спину» в спящем режиме?Стоит ли очищать перед отправкой запроса сервлету?

Ответы [ 2 ]

3 голосов
/ 17 марта 2012

Это нормальное и ожидаемое поведение.Если бы Hibernate выполнял запрос на обновление каждый раз при изменении постоянного свойства, производительность была бы катастрофической.Состояние всех измененных объектов сохраняется в базе данных во время сброса.Сброс происходит

  • во время фиксации
  • при явном вызове session.flush() или entityManager.flush()
  • при выполнении запроса (HQL или Критерии), который запрашиваетодна из таблиц измененных сущностей

Таким образом, у вас не должно быть никаких ошибок, за исключением случаев, когда вы выполняете запрос «за спиной» Hibernate, используя JDBC или какой-либо собственный запрос.Если это так, перед выполнением этого запроса явно очистите его.

1 голос
/ 18 марта 2012

При работе с ORM необходимо учитывать транзакцию. ORM работает в рамках транзакции и, как правило, сохраняет изменения в БД, когда 1) tx завершает работу, 2) попадает в какой-то внутренний маркер или 3) когда ему специально дается указание сбросить в БД, так как Дж. Б. Низет отметил.

Если ваш код зависит от конкретного состояния БД для данного объекта, например, другая часть вашего кода возвращается в БД для получения данных, и эта часть кода зависит от того, находится ли этот объект в определенном состоянии Возможно, вам придется вернуться к своему коду и переосмыслить, как он написан. Возможно, вызовы должны выполняться в разных транзакциях, или объекты на вашем уровне ORM могут иметь отношения, которые не были установлены в ваших объектах (например, OneToMany).

В общем, вам действительно не нужно делать руководство flushes; ORM, как правило, очень компетентны для учета зависимостей при сбросе в базу данных. Фактически, из моего собственного опыта я обнаружил, что при правильной настройке сущности я кодировал только руководство flushes при выполнении пакетного кодирования, согласно руководству Hibernate.

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