如何在查询执行期间停止会话以保存未保存的对象?

时间:2010-09-02 13:33:54

标签: hibernate

我遇到会话和查询执行问题,请参阅下面的代码。

class A implements Lifecycle{

 public boolean onUpdate(Session session){
     Query test=session.createQuery("select * from Unknown");
     List list=test.list();
     B b=new B();
     session.save(b);
 }

}
class B{
  C c;
  public B(){
    c=new C();
   c.a=new A();
  }

}
class C implements Lifecycle{
  A a;
  public boolean onSave(Session session){
     a.onUpdate(session);
  }

}

每当我调用方法a.onUpdate()时,我修改了一个对象并调用了onUpdate方法。但是异常

org.hibernate.TransientObjectException:object引用未保存的瞬态实例 - 在刷新之前保存瞬态实例:com.test.C

由于onUpdate方法中的查询执行,我知道上面的异常。请建议我在查询执行时有办法停止保存未保存的对象。或任何其他表明这个问题非常有帮助。

1 个答案:

答案 0 :(得分:2)

  

请建议我在查询执行期间有办法停止保存未保存的对象

要严格回答这个问题,默认情况下,Hibernate在执行查询时确实会刷新会话,这样您就不会得到陈旧的结果。您可以使用自定义FlushMode(COMMIT或NEVER)更改此行为。来自文档:

  

10.10. Flushing the Session

     

有时会话会执行   需要同步的SQL语句   JDBC连接的状态与   内存中保存的对象状态。这个   进程,称为刷新,发生   默认为以下几点:

     
      
  • 在某些查询执行之前
  •   
  • 来自org.hibernate.Transaction.commit()
  •   
  • 来自Session.flush()
  •   
     

SQL语句发布于   以下顺序:

     
      
  • 所有实体插入的顺序与相应的对象相同   使用Session.save()
  • 保存   
  • 所有实体更新
  •   
  • 所有集合删除
  •   
  • 所有集合元素删除,更新和插入
  •   
  • 所有收集插入
  •   
  • 所有实体删除的顺序与对应的对象相同   已使用Session.delete()
  • 删除   
     

一个例外是对象使用   插入本机ID时生成   他们得救了。

     

除非您明确flush(),   绝对没有保证   关于Session何时执行   JDBC调用,只有其中的顺序   他们被处决了。但是,Hibernate   确保保证   Query.list(..)永远不会回来   陈旧或不正确的数据。

     

可以更改默认值   行为使得冲洗发生得更少   经常。 FlushMode班   定义了三种不同的模式:仅限   在提交时刷新   使用Hibernate Transaction API,   使用自动冲洗   解释常规,或从不冲洗   除非明确调用flush()。   最后一种模式很有用   运行工作单元,其中一个会话   保持打开状态并断开连接   很长时间(见Section 11.3.2, "Extended session and automatic versioning")。

sess = sf.openSession();
Transaction tx = sess.beginTransaction();
sess.setFlushMode(FlushMode.COMMIT); // allow queries to return stale state

Cat izi = (Cat) sess.load(Cat.class, id);
izi.setName(iznizi);

// might return stale data
sess.find("from Cat as cat left outer join cat.kittens kitten");

// change to izi is not flushed!
...
tx.commit(); // flush occurs
sess.close();
     

在刷新期间,可能会发生异常   (例如,如果DML操作违反了   约束)。自处理异常以来   涉及到一些了解   Hibernate的事务行为,我们   在Chapter 11, Transactions and Concurrency中讨论它。

但老实说,我不确定你要做什么(也许这只是一个样本,但你的HQL查询不正确)。

参考