0

i'm trying to do a full CRUD using a collection of detached objects (ie they were created without using hibernate and are not associated with the session).

the ids of the items are user defined (not generated).

the collection contains entries that already exist in the database and entries that don't exist in the database.

existing entries should be updated, new entries should be inserted.

any entries that exist in the database but not in the collection should be deleted.

so far i have been trying to delete all entries from the database first, then perform a saveOrUpdate on each item in the collection:

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

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

however this results in the error

a different object with the same identifier value was already associated with the session

i assumed this was because the delete loop was loading an object into the session, and i was then attempting to save a different object with the same id later, so i changed the code so that i evicted each delete entity:

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

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

and now i'm getting

org.hibernate.AssertionFailure: possible nonthreadsafe access to session

what is the least exhaustive method of performing this kind of operation.

note: i need this to happen within one transaction in-case anything doesn't work i don't want the data load to have any effect.

thanks.

pstanton
  • 35,033
  • 24
  • 126
  • 168

1 Answers1

2

You should not, IMO, delete all entities before saving them again. Instead, I would

  • find all the entities,
  • compare the new collection with the found one and identify wich entities must be deleted
  • delete those entities
  • merge the other ones (using the merge method, which will copy the state of your detached entities to the attached ones, even if they are already in the session)

Note that the first and second steps could be done by finding all the entities except those whose ID is in your collection of detached entities : "select e from Entity e where e.id not in (:idsOfDetachedEntities)"

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • This might be helpful also: http://stackoverflow.com/questions/1667481/compare-two-lists-for-updates-deletions-and-additions – Pablojim Jan 21 '11 at 13:04