Hibernate v3.6: проблема с методом обновления "EntityManager" - PullRequest
1 голос
/ 23 октября 2010

Следующий код вызывает исключение при вызове «em.refresh (p)»:

1: EntityManager em = emf.createEntityManager();
2: em.getTransaction().begin();
3:
4: Product p = new Product("J&D", 35.0,"Whisky");
5: em.persist(p);
6:
7: em.refresh(p);
8: em.getTransaction().commit();
9: em.close();

При отладке кода мы видим, что Hibernate не записал запись в БД в строке 6Он делает, как и предполагалось - когда это требуется, а не раньше.

В строке 7 мы получаем следующее исключение: Исключение в потоке "main" javax.persistence.PersistenceException: org.hibernate.HibernateException: этот экземпляреще не существует в виде строки в базе данных

Когда мы заставляем Hibernate сбросить запись в БД в строке 6, выполняется INSERT, и ошибка не возникает.Мы можем сделать это, выполнив выбор или просто принудительно сбросив (со всеми вытекающими последствиями):

6 : em.createQuery("select p from Product p").getResultList();
6 : em.flush();

Мой вопрос: должен ли метод «обновить» не заставлять Hibernate записывать запись в БД, как это делаетоператор select или flush ранее не размещался?(Может быть, это ошибка?).

Заранее спасибо за ваши ответы.

Пьер

1 Ответ

5 голосов
/ 23 октября 2010

должен ли метод "refresh" не заставлять Hibernate записывать запись в БД, как это делает оператор select или flush при размещении ранее? (Может быть, это ошибка?).

Нет, refresh не должно сбрасывать изменения, поскольку весь смысл refresh в том, чтобы отменить любые не очищенные изменения, сделанные в текущей транзакции . Это может быть лучше объяснено в вики-книге JPA, чем в спецификации:

The EntityManager#refresh(Object) операция используется для обновления состояние объекта из базы данных. это отменит любые не очищенные изменения сделано в текущей транзакции объект, и обновить его состояние до того, что в настоящее время определено в базе данных. Если произошел flush, он будет обновить до того, что было покраснело. обновление должен быть вызван на управляемом объекте, так сначала вам может понадобиться find объект с активным EntityManager, если вы иметь неуправляемый экземпляр.

Так что вы действительно должны flush после persist, если хотите, чтобы ваш код работал.

Как говорится, я не вижу смысла делать refresh сразу после persist (при условии, что вы сбросили изменения), здесь просто нечего обновлять. Может быть, это просто упрощенный пример.

Ссылки

  • спецификация JPA 2.0
    • 3.2.5 Обновление экземпляра сущности
  • JPA Wiki book
...