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

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

问题描述

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

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

我知道 session.close() 通常不会刷新会话,但我不确定 FlushMode.AUTO 对此有何影响.

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

来自文档:

FlushMode.AUTO
Session 有时会在查询执行之前刷新,以确保查询永远不会返回陈旧状态.这是默认的刷新模式.

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.

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

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

小代码示例:

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

更新
根据文档这些是会话将刷新的地方(使用 AUTO 时)

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

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

这并没有说明 Session.close()

This does not say anything about Session.close()

推荐答案

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

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(); 

默认情况下,在 Java SE 环境中使用 JDBC 配置,这是如果你执行这个会发生什么片段:

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

  1. 打开一个新会话.此时不获取数据库连接点.
  2. 调用 get() 会触发 SQL SELECT.Session 现在获得了一个 JDBC来自连接池的连接.默认情况下立即休眠关闭自动提交模式与 setAutoCommit(false) 的连接.这有效地启动了一个 JDBC交易!
  3. SELECT 在此 JDBC 事务中执行.会议是关闭,并返回连接到池中并由 Hibernate 释放— Hibernate 在 JDBC 上调用 close()联系.会发生什么未提交的事务?

这个问题的答案是,它要看!"JDBC 规范没有说任何关于待定的事情调用 close() 时的事务一个连接.会发生什么取决于供应商如何实施规格.使用 Oracle JDBC驱动程序,例如,调用close() 提交事务!最多其他 JDBC 供应商采取理智的路线并回滚任何待处理的事务当 JDBC Connection 对象是关闭并返回资源游泳池.

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.

显然,这不会成为问题你已经执行的 SELECT ,但是看看在这个变化:

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(); 

此代码导致插入语句,在一个内部执行从未提交的事务或回滚.在 Oracle 上,这块代码永久插入数据;在其他数据库,可能没有.(这个情况略多复杂:执行 INSERT仅当标识符生成器需要它.例如,一个标识符值可以从没有 INSERT 的序列.该持久实体然后排队直到刷新时间插入 - 从不发生在这段代码中.一个身份策略需要立即插入用于要生成的值.)

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天全站免登陆