我遇到会话和查询执行问题,请参阅下面的代码。
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方法中的查询执行,我知道上面的异常。请建议我在查询执行时有办法停止保存未保存的对象。或任何其他表明这个问题非常有帮助。
答案 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查询不正确)。