Ошибка возникает потому что пытаемся сохранить/удалить/проапдейтить объект из другой сессии, который уже загружен в нашей сессии(закэширован).
Лечение:
1) 100% лекарство использовать hibernateTemplate.merge(object);
2) 100% лекарство которое приводит к обнулению всего кэша
hibernateTemplate.flush();
hibernateTemplate.clear();
hibernateTemplate.saveOrUpdate(object);
3) лекарство может не помочь
hibernateTemplate.evict(object); - убирает объекты из кэша сравнивая их по объектной ссылке
hibernateTemplate.saveOrUpdate(object); - проверяет наличие объектов в кэше(прежде чем их сохранить) по айдишнику. Вывод: такая пара смысла не имеет(ну, имеет смысл в рамках одной сессии и совсем для другого).
Можно написать так:
Class dataObjectClass = object.getClass();
long id = object.getId();
T dataObject = (T) hibernateTemplate.get(dataObjectClass, id);
if (dataObject != null) {
hibernateTemplate.evict(dataObject );
}
Но это спасёт нас только в том случае - если в ентитях нигде нету перекрёстных ссылок. Если они есть - то при каскадном сохранении будут ентити добавляться в кэш по нескольку раз и в результате получим тот же иксэпшн(Зы: иксэпшн будет валиться непосредственно при комите транзакции и всякие flush перед evict тут непомогут).
4) делать всё в одной сессии
5)загрузить по id, выставить необходимые поля, сохранить
Подписаться на:
Комментарии к сообщению (Atom)
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/objectstate.html
ОтветитьУдалитьhttp://pro-programmers.blogspot.com/2009/03/hibernate-nonuniqueobjectexception.html
ОтветитьУдалить