在使用FlushMode.AUTO调用session.close()时,Hibernate会刷新更新的持久对象吗? [英] Will Hibernate flush my updated persistent object when calling session.close() with FlushMode.AUTO?

查看:108
本文介绍了在使用FlushMode.AUTO调用session.close()时,Hibernate会刷新更新的持久对象吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果设置了FlushMode.AUTO,当我调用session.close()时,Hibernate会刷新更新的持久对象吗?



我知道session.close通常不需要刷新会话,但我不确定FlushMode.AUTO如何影响此操作。



来自文档:

< blockquote>

FlushMode.AUTO

会话在查询执行前有时被刷新以确保查询永不返回陈旧状态。这是默认的刷新模式。


这是否意味着我可以依靠Hibernate来验证我的更改在我的会话关闭之前有时被刷新

小代码例子:

 会话会话= HibernateSessionFactory.getSession (); 
PersistedObject p = session.get(PersistedObject.class,id);
p.setSomeProperty(newValue);
session.close();

更新

根据文档这些是会话的地方会在执行某些查询之前刷新(使用AUTO时)


  • org.hibernate中的
  • 。 Transaction.commit()

  • 来自Session.flush()



关于Session.close()

解决方案

当调用session.close时,Hibernate会刷新更新后的持久对象()(使用FlushMode.AUTO)?

不,它应该不会,你应该使用定义良好的事务边界即可。引用非事务性数据访问和自动提交模式


使用Hibernate非交易式工作



查看下面的代码,其中
访问没有$ b $的数据库b交易界限:

 会话会话= sessionFactory.openSession(); 
session.get(Item.class,123l);
session.close();

默认情况下,在JDBC配置的Java SE环境
中,这是
如果您执行此
代码段,会发生什么情况:


  1. 打开新会话。它不会在
    点获得数据库连接。
  2. 调用get()会触发SQL SELECT。会话现在从连接池中获得一个JDBC
    连接。
    默认情况下,Hibernate立即
    关闭这个
    连接上的自动提交模式,并使用setAutoCommit(false)。
    这有效地启动了JDBC
    事务!

  3. SELECT在此JDBC事务中执行。 Session是关闭的
    ,连接返回
    到池并由Hibernate释放
    - Hibernate在JDBC
    Connection上调用close()。
    未提交的交易会发生什么?

这个问题的答案是It
depends!当在
a连接上调用close()时,JDBC规范
没有提及有关未完成的
事务的任何内容。发生什么取决于
供应商如何实现
规格。例如,使用Oracle JDBC
驱动程序调用
close()提交事务!当JDBC Connection对象关闭
并且资源返回到池
时,大多数
其他JDBC供应商采用理智的路线
并回退任何待处理的事务



显然,这对您执行的SELECT
不会造成问题,但在这种变体中查看

  Session session = getSessionFactory()。openSession(); 
Long generatedId = session.save(item);
session.close();

此代码产生一个INSERT
语句,该语句在
事务中执行,从未提交或
回滚。在Oracle上,这块
代码永久插入数据;在
其他数据库中,它可能不是。 (这个
的情况稍微多一些
复杂:只有当标识符生成器
需要时才执行INSERT
。例如,
标识符值可以从没有INSERT的
a序列
持久化实体然后排队,直到
刷新时间插入 - 这个代码从未发生过
。身份
策略要求立即使用INSERT
作为生成的值。)

底线:使用明确的事务划分。


If FlushMode.AUTO is set, will Hibernate flush my updated persistent object when I call session.close()?

I know that session.close() does not normally flush the session but I'm not sure how FlushMode.AUTO affects this.

From the Docs:

FlushMode.AUTO
The Session is sometimes flushed before query execution in order to ensure that queries never return stale state. This is the default flush mode.

Does this mean I can rely on Hibernate to verify my changes are flushed sometimes before my session is closed?

Small code example:

Session session = HibernateSessionFactory.getSession();  
PersistedObject p = session.get(PersistedObject.class,id);  
p.setSomeProperty(newValue);  
session.close();

UPDATE
According to the docs these are the places where the session will flush (when AUTO is used)

  • before some query executions
  • from org.hibernate.Transaction.commit()
  • from Session.flush()

This does not say anything about Session.close()

解决方案

Will Hibernate flush my updated persistent object when calling session.close() (using FlushMode.AUTO)?

No it won't, and you should use a transaction with well defined boundaries. Quoting Non-transactional data access and the auto-commit mode:

Working nontransactionally with Hibernate

Look at the following code, which accesses the database without transaction boundaries:

Session session = sessionFactory.openSession(); 
session.get(Item.class, 123l); 
session.close(); 

By default, in a Java SE environment with a JDBC configuration, this is what happens if you execute this snippet:

  1. A new Session is opened. It doesn’t obtain a database connection at this point.
  2. The call to get() triggers an SQL SELECT. The Session now obtains a JDBC Connection from the connection pool. Hibernate, by default, immediately turns off the autocommit mode on this connection with setAutoCommit(false). This effectively starts a JDBC transaction!
  3. The SELECT is executed inside this JDBC transaction. The Session is closed, and the connection is returned to the pool and released by Hibernate — Hibernate calls close() on the JDBC Connection. What happens to the uncommitted transaction?

The answer to that question is, "It depends!" The JDBC specification doesn’t say anything about pending transactions when close() is called on a connection. What happens depends on how the vendors implement the specification. With Oracle JDBC drivers, for example, the call to close() commits the transaction! Most other JDBC vendors take the sane route and roll back any pending transaction when the JDBC Connection object is closed and the resource is returned to the pool.

Obviously, this won’t be a problem for the SELECT you’ve executed, but look at this variation:

Session session = getSessionFactory().openSession(); 
Long generatedId = session.save(item); 
session.close(); 

This code results in an INSERT statement, executed inside a transaction that is never committed or rolled back. On Oracle, this piece of code inserts data permanently; in other databases, it may not. (This situation is slightly more complicated: The INSERT is executed only if the identifier generator requires it. For example, an identifier value can be obtained from a sequence without an INSERT. The persistent entity is then queued until flush-time insertion — which never happens in this code. An identity strategy requires an immediate INSERT for the value to be generated.)

Bottom line: use explicit transaction demarcation.

这篇关于在使用FlushMode.AUTO调用session.close()时,Hibernate会刷新更新的持久对象吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆