Следующий код пытается вставить объект Item
в базу данных, используя Spring + Hibernate.Элемент имеет поле идентификатора Integer в качестве первичного ключа, а также столбец name
, который подчиняется уникальному ограничению (упрощенный пример).
Я знаю, что идентификатор элемента равен нулю (элемент является временным), однаковставка может все еще завершиться неудачей из-за уникального ограничения на поле имени.
try {
getHibernateTemplate().save(myItem);
getHibernateTemplate().flush(); // exception thrown here if the name is not unique
}
catch (DataIntegrityViolationException e) {
Item itemFromDb = (Item) getHibernateTemplate()
.find("from Item item where item.name = ?",
myItem.getName()).get(0);
//
// copy some properties from myItem to itemFromDb
//
getHibernateTemplate.update (itemFromDb)
}
Мне нужен этот код для запуска в цикле для многих элементов, все в одной транзакции, поэтому я пытаюсь выпустить обновлениеесли вставка не удалась.
Однако после неудачной вставки сеанс гибернации находится в странном состоянии, и когда я выполняю инструкцию select для получения элемента из БД, original исключение.
Я попытался использовать session.evict()
после сбоя вставки, но безрезультатно.Есть идеи?
Это то, что я вижу в консоли после неудачного выбора.Hibernate завершается с ошибкой в операторе select, но все равно печатает информацию о предыдущем операторе вставки.
WARN [http-8080-1] hibernate.util.JDBCExceptionReporter (JDBCExceptionReporter.java:77) - SQL Error: 2627, SQLState: 23000
ERROR [http-8080-1] hibernate.util.JDBCExceptionReporter (JDBCExceptionReporter.java:78) - Violation of UNIQUE KEY constraint 'unq_Item_name'. Cannot insert duplicate key in object 'items'.
ERROR [http-8080-1] event.def.AbstractFlushingEventListener (AbstractFlushingEventListener.java:301) - Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: could not insert: [com.sample.Item]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
PS Пожалуйста, не говорите мне о методе saveOrUpdate в hibernate, я знаю, что он делает.