我正在尝试将最初从数据库中检索到的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();
答案 0 :(得分:1)
我担心目前没有击中DB是不可能的。 显然,由于锁定命令而发生异常。
有一个Jira报告了这种行为 https://hibernate.atlassian.net/browse/HHH-511
它有2个补丁来解决问题。你可以尝试那些补丁。
但如果您只是延迟加载集合,则可以考虑使用 Open Session In View 模式。 (也许不是最好的模式,但它可以适用于你的情况)