java - 如何在查询执行期间停止 session 以保存已保存的对象?

标签 java hibernate orm session

我在 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 the Query.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 unless flush() 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/

相关文章:

java - 使用 Java/Scala 创建文档的格式化 PNG 'pages'

java - Jar 文件无法运行,提取的类运行正常

ruby-on-rails - ActiveRecord 的 ORM 替代品

java - 使用抽象类(不带表)持久保存层次结构的最佳方法是什么

Java检查整数平方是否导致溢出

java - 无法将 NULL 插入列

java - 无法使用 hibernate 从 oracle 表中选择数据

javax.validation.NotBlank 缺少 validator

python - Django 中的高级数据库查询

python - sqlalchemy 标量查询问题?