以下代碼嘗試使用Spring + Hibernate將Item
對象插入到數據庫。該項目有一個Integer ID字段作爲主鍵,以及一個受限於唯一約束的name
列(簡化示例)。
我知道該項目的ID爲空(該項目是瞬態的),但插入可能仍然失敗,因爲名稱字段上的唯一約束。在失敗的插入後恢復Hibernate會話狀態
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語句從db獲取該項時,會引發原始異常。
我試過在插入失敗後使用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)
P.S.請不要告訴我關於hibernate的saveOrUpdate方法,我知道它做了什麼。
也許最好在插入/更新之前進行選擇? – 2010-02-17 15:34:09