2011-01-21 5 views
0

Я пытаюсь выполнить полный CRUD, используя коллекцию отдельных объектов (т. Е. Они были созданы без использования спящего режима и не связаны с сеансом).проблемы с сбором коллекции

Идентификаторы элементов определены пользователем (не сгенерированы).

В коллекции содержатся записи, которые уже существуют в базе данных, и записи, которые не существуют в базе данных.

существующие записи должны быть обновлены, новые записи должны быть вставлены.

любые записи, которые содержатся в базе данных, но не в коллекции, должны быть удалены.

до сих пор я пытался удалить все записи из базы данных, а затем выполнить saveOrUpdate по каждому пункту в коллекции:

for (Object entity : session.createCriteria(type).list()) 
    session.delete(entity); 

for (Object entity : collection) 
    session.saveOrUpdate(entity); 

однако это приводит к ошибке

другой объект с тем же значением идентификатора уже был , связанный с сеансом

Я предполагал, что это связано с тем, что цикл delete загружал объект в сеанс, и затем я пытался сохранить другой объект с тем же идентификатором позже, поэтому я изменил код, чтобы я удалил каждый удаляемый объект:

for (Object entity : session.createCriteria(type).list()) 
{ 
    session.delete(entity); 
    session.evict(entity); 
} 

for (Object entity : collection) 
    session.saveOrUpdate(entity); 

и теперь я получаю

org.hibernate.AssertionFailure: возможно nonthreadsafe доступ к сессии

, что является наименее exhaustiv e метод выполнения такого рода операций.

примечание: мне нужно, чтобы это произошло в пределах одной транзакции в любом случае ничего не работает, я не хочу, чтобы загрузка данных имела какой-либо эффект.

спасибо.

ответ

2

Вы не должны, ИМО, удалять все сущности перед сохранением их снова. Вместо этого я бы

  • найти все объекты,
  • сравнить новую коллекцию с найденным одним и определить которым объекты должны быть удалены
  • удалить эти сущности
  • сливаться другие из них (с помощью слияния метод, который скопирует состояние ваших отдельных объектов на присоединенные, даже если они уже находятся в сеансе).

Обратите внимание, что первый и второй шаги могут быть выполнены путем нахождения всех прав кроме тех, чей идентификатор находится в вашей коллекции отдельных объектов: «выберите e из Entity e, где e.id not in (: idsOfDetachedEntities) "

+0

Это может быть полезно также: http://stackoverflow.com/questions/1667481/compare-two-lists-for-updates-deletions-and-additions – Pablojim

Смежные вопросы