Hibernate * НЕ * выбрасывает исключение (я думаю, что должно) - PullRequest
6 голосов
/ 04 июня 2009

Hibernate JavaDoc утверждает, что Session.update(Object o) вызовет исключение, если уже существует постоянный экземпляр o, верно?

If there is a persistent instance with the same identifier, an exception is thrown.

Однако следующий код ничего не выдает при запуске. И я думаю, что это должно!

Email email = new Email("andre", "girafa", "hi");

Session session = factory.openSession();
Transaction tx = session.beginTransaction();

session.save(email);
session.update(email);
session.update(email);

tx.commit();

// didn't throw... Let's try again

tx = session.beginTransaction();

session.update(email);
session.update(email);

tx.commit();
session.close();

// still nothing! :(

Как вы можете сказать, дважды Я пытаюсь сделать несколько раз update() с, но Hibernate все еще чувствует себя спокойно.

У кого-нибудь есть догадка, почему?

РЕДАКТИРОВАТЬ: кажется, что он бросил бы, только если другой эквивалентный объект , например, email2 с таким же идентификатором, как email. Я предполагаю, что документация там была немного неаккуратной.

Ответы [ 4 ]

8 голосов
/ 04 июня 2009

Обновление в Hibernate не является ОБНОВЛЕНИЕМ в языке SQL. Hibernate обрабатывает обновления SQL автоматически через кэш состояния в объекте Session.

Но это только для сущностей, загруженных в текущем сеансе. Этот метод, session.update (object) предназначен для присоединения объекта из другого уровня к текущему сеансу для отслеживания и, возможно, обновления в конце.

В вашем случае это просто НООП. Кисло бросит, если:

Email email = new Email("andre", "girafa", "hi");

Session session = factory.openSession();
Transaction tx = session.beginTransaction();

int id = session.save(email);
Email anotherEmail = new Email("", "", "");
anotherEmail.id = id;

session.update(anotherEmail);    // will throw

Вы можете прочитать больше о семантике метода обновления в Ссылка на Hibernate .

6 голосов
/ 04 июня 2009

Нет ошибок, потому что вы обновляете тот же экземпляр.

Ошибка выдается, если в сеансе присутствует РАЗЛИЧНЫЙ постоянный экземпляр, и вы пытаетесь обновить ().

0 голосов
/ 02 июля 2018

Я предлагаю вам всегда придерживаться EntityManager.merge вместо метода Hibernate update, update довольно запутанно.

Я нашел эту статью Объясняю очень ясно, к чему я всегда обращаюсь.

Как и в случае с сохранением и сохранением, метод обновления является «оригинальным» Hibernate метод, который присутствовал задолго до того, как был добавлен метод слияния. это Семантика отличается в нескольких ключевых моментах:

  • действует на переданный объект (его тип возврата void); метод обновления переводит переданный объект из отключенного в постоянный
    государство;
  • этот метод выдает исключение, если вы передаете ему временную сущность.

В следующем примере мы сохраняем объект, а затем выселяем его из контекста, затем измените его имя и вызовите обновление. Обратите внимание, что мы не помещайте результат операции обновления в отдельную переменную, потому что обновление происходит на самом объекте person. В принципе мы подключаем существующий экземпляр сущности к постоянству контекст - то, что спецификация JPA не позволяет нам делать.

Person person = new Person();
person.setName("John");
session.save(person);
session.evict(person);

person.setName("Mary");
session.update(person);

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

Person person = new Person();
person.setName("John");
session.update(person); // PersistenceException!

Чтобы понять вышеприведенную часть, вам необходимо понять разницу между transient и detached объектом.

0 голосов
/ 04 июня 2009

Можете ли вы попробовать с session.flush ()? Чтобы увидеть, вызывает ли это исключение (иногда фиксация может не сбрасывать данные в зависимости от режима сброса).

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

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