2015-12-13 1 views
3

Клиентское приложение поставляет устаревший объект, который должен быть объединен Hibernate. Простейший пример.Hibernate неожиданно вызывает INSERT вместо того, чтобы бросать javax.persistence.OptimisticLockException, когда несуществующий объект передается в merge()

public Entity update(Entity entity) { 
    return entityManager.contains(entity) ? entity : entityManager.merge(entity); 
} 

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

Оптимистическая блокировка была включена путем введения поля @Version в предоставленном объекте.

Когда объект, который будет объединен, уже был удален, ожидается, что будет выброшено javax.persistence.OptimisticLockException, которого не произойдет. Hibernate выполняет INSERT, что совершенно неожиданно. Вставка устаревшего объекта вместо того, чтобы выбрасывать javax.persistence.OptimisticLockException, - это что-то против блокировки.

«Вставить или обновить» - это история, которая должна быть приостановлена ​​путем выброса javax.persistence.OptimisticLockException, если устаревший или удаленный (несуществующий) объект передается в merge(), если реализована оптимистическая блокировка.

EclipseLink выбрасывает javax.persistence.OptimisticLockException, как ожидалось, в случае, если устаревший или удаленный/несуществующий объект передается в merge().

Есть ли способ сделать Hibernate броском javax.persistence.OptimisticLockException, когда устаревший или несуществующий объект передан в merge()?

Я ожидаю, что в persistence.xml должно быть какое-то конфигурируемое свойство, чтобы применить его в глобальном масштабе или в аннотациях для применения к определенному объекту.

В настоящее время я использую Hibernate 5.0.5 final.


Обновлено до Hibernate 5.0.6 final.

+1

Это давняя ошибка в спящем режиме. Вы можете проголосовать за него: https://hibernate.atlassian.net/browse/HHH-1661 –

+0

Вопрос о десятилетнем возрасте. – Tiny

+0

Я думаю, новая новая проблема должна быть создана. Отчет о проблеме вряд ли будет принят во внимание, поскольку он довольно старый. Это критическая ошибка, которая не может быть воспринята легко и должна быть исправлена ​​как можно скорее. – Tiny

ответ

0

Try EntityManager.refresh вместо EntityManager.merge, и проверить, если объект имеет значение идентификатора, если да, установить новые значения и после EntityManager.merge, если не объект был удален

что-то вроде этого

public Entity update(Entity entity) { 

    entityManager.refresh(entity); 

    if (entity.getId() != null) { 
     // my entity is in database 
     // set my changes in entity 
     return entityManager.merge(entity); 
    } else { 
     // my entity has been deleted 
     return null; 
    } 
} 

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

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