Я пытаюсь повторно присоединить к сеансу объект из сеанса HTTP, который был первоначально получен из БД, я делаю это, вызывая session.lock(object, LockMode.None)
, и хотя блокировка не работает каскадно, для меня это работает нормально, потому что это делает не загружать обновления в БД, как merge
(блокировка необходима для открытия подробного представления во всплывающем окне, а фактическое сохранение будет происходить позже в главном окне). Теперь, к моему удивлению, я обнаружил, что если моя сущность имеет отношение один ко многим, любые изменения в этой коллекции вызовут HibernateException
«Повторно связанный объект имеет грязную коллекцию».
Как я могу присоединить объекты к сеансу, не обновляя БД и не отменяя изменения в объекте?
Вот ситуация как код
EntityA t = createAnEntityA();
Session sess = factory.openSession();
sess.beginTransaction();
sess.save(t);
sess.getTransaction().commit();
sess.close();
// t is now saved on the DB but in dettached state
// change a simple property
sess = factory.openSession();
sess.beginTransaction();
t.setPropertyB("B");
sess.lock(t, LockMode.NONE);
// t is attached again, you won't get LazyInitializationException
// by calling its properties, although you have to be careful
// because the reattachment does not cascade to children
sess.getTransaction().commit();
sess.close();
// no updates went to the DB because setPropertyB was called
// when t was still dettached
// now change a collection
EntityC c = createAnEntityC();
t.getCollectionPropertyC().add(c);
sess = factory.openSession();
sess.beginTransaction();
sess.lock(t, LockMode.NONE);
// Exception is thrown :-(
sess.getTransaction().commit();
sess.close();