восстановитесь В спящем режиме состояние сеанса после неудавшейся вставки

Следующий код пытается вставить Item возразите против дб, с помощью Spring+Hibernate. Объект имеет Целочисленное идентификационное поле как первичный ключ, а также a 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)
}

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

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

Я пытался использовать session.evict() после сбоев вставки, но напрасно. Какая-либо идея?

Это - то, что я вижу в консоли после избранных сбоев. Будьте в спящем режиме сбои на избранном операторе, но все еще печатает информацию о предыдущем операторе вставки.

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)

P.S. не говорите мне о saveOrUpdate методе hibernate, я знаю то, что он делает.

5
задан Yoni 17 February 2010 в 15:23
поделиться

2 ответа

Hibernate не дает никаких гарантий относительно сеанса после того, как возникло исключение базы данных. Вы должны откатиться. Если я понимаю предложение Божо, он говорит, что вы должны сначала прочитать столбец имени, чтобы убедиться, что вставка не потерпит неудачу. Для меня это имеет смысл.

3
ответ дан 15 December 2019 в 00:59
поделиться
getHibernateTemplate().merge(myItem);

merge - копирование состояния данного объекта на постоянный объект с тем же идентификатором. Если в настоящее время нет постоянного экземпляра, связанного с сессией, он будет загружен. Вернуть постоянный экземпляр. Если данный экземпляр не сохранен, сохраните его копию и верните ее как новый персистентный экземпляр. Данный экземпляр не становится ассоциированным с сессией. Эта операция каскадируется на ассоциированные экземпляры, если ассоциация отображена с cascade="merge".

1
ответ дан 15 December 2019 в 00:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: