我在 session 和查询执行方面遇到问题,请参阅下面的代码。
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 方法。但是每当我调用方法 a.onUpdate(); 时都会出现异常
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.test.C
我知道上述异常是由于 onUpdate 方法中的查询执行造成的。请建议我是否有办法在查询执行期间停止保存未保存的对象。或对上述问题的任何其他建议都非常有帮助。
最佳答案
please suggest me is there is way to stop to save unsaved objects during queries execution
为了严格回答这个问题,默认情况下,Hibernate 在执行查询时确实会刷新 session ,这样您就不会得到过时的结果。您可以使用自定义 FlushMode
(COMMIT 或 NEVER)更改此行为。来自文档:
10.10. Flushing the Session
Sometimes the Session will execute the SQL statements needed to synchronize the JDBC connection's state with the state of objects held in memory. This process, called flush, occurs by default at the following points:
- before some query executions
- from
org.hibernate.Transaction.commit()
- from
Session.flush()
The SQL statements are issued in the following order:
- all entity insertions in the same order the corresponding objects were saved using
Session.save()
- all entity updates
- all collection deletions
- all collection element deletions, updates and insertions
- all collection insertions
- all entity deletions in the same order the corresponding objects were deleted using
Session.delete()
An exception is that objects using native ID generation are inserted when they are saved.
Except when you explicitly
flush()
, there are absolutely no guarantees about when the Session executes the JDBC calls, only the order in which they are executed. However, Hibernate does guarantee that theQuery.list(..)
will never return stale or incorrect data.It is possible to change the default behavior so that flush occurs less frequently. The
FlushMode
class defines three different modes: only flush at commit time when the Hibernate Transaction API is used, flush automatically using the explained routine, or never flush unlessflush()
is called explicitly. The last mode is useful for long running units of work, where a Session is kept open and disconnected for a long time (see 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();
During flush, an exception might occur (e.g. if a DML operation violates a constraint). Since handling exceptions involves some understanding of Hibernate's transactional behavior, we discuss it in Chapter 11, Transactions and Concurrency.
但老实说,我不确定您要做什么(也许这只是一个示例,但您的 HQL 查询不正确)。
引用文献
关于java - 如何在查询执行期间停止 session 以保存已保存的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3626982/