다음 코드는 Spring + Hibernate를 사용하여 Item
개체를 db에 삽입하려고 시도합니다. 항목에는 기본 키로 정수 ID 필드가 있고 고유 제한 조건 (단순화 된 예)이 적용되는 name
열이 있습니다.
항목의 ID가 null (항목이 일시적 임)이지만 name 필드의 고유 제한 조건으로 인해 삽입이 여전히 실패 할 수 있음을 알고 있습니다.삽입 실패 후 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)
}
는 내가 삽입이 실패 할 경우 업데이 트를 발행하려고 그 이유는, 모두 하나의 트랜잭션에서 여러 항목에 대한 루프에서 실행하려면이 코드가 필요합니다.
그러나 삽입이 실패한 후 최대 절전 모드 세션이 이상한 상태이며 db에서 항목을 가져 오기 위해 select 문을 실행하면 원래 예외가 발생합니다.
삽입이 실패한 후에 session.evict()
을 사용해 보았지만 아무 소용이 없었습니다. 어떤 생각?
이것은 선택 실패 후 콘솔에 표시됩니다. Hibernate는 select 문에서 실패하지만 여전히 이전의 insert 문에 대한 정보를 출력한다.
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. 최대 절전 모드의 saveOrUpdate 메소드에 대해 알려주지 마라.
아마도 삽입/업데이트 전에 선택을하는 것이 더 좋을까요? –