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

标签 java hibernate session flush

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

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

来自文档:

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 来验证我的更改有时会在我的 session 关闭之前刷新?

小代码示例:

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

更新
根据the docs这些是 session 将刷新的地方(当使用 AUTO 时)

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

这并没有说明任何关于 Session.close() 的内容

最佳答案

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

不,它不会,您应该使用具有明确边界的事务。引用 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.)

底线:使用显式事务划分。

关于java - 当使用 FlushMode.AUTO 调用 session.close() 时,Hibernate 会刷新我更新的持久对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3931162/

相关文章:

php - 在 session 中存储值并在 tpl 文件 xcart 上检索

java - Raspberry Pi 路由器上的组播

java - XML API 或开源 jar,用于根据给定路径提取 XML 子集

java - Hibernate session.get() UUID 字符串 ID 问题

java - 消除计算字段上的 LazyInitializationException 的最佳方法是什么?

java - onClick 到另一个 JSP 不起作用

php session 变量在下一页丢失

java - 你能帮助理解如何使用 JOIN 与 spring-repository 吗?

java - 广告不可见。不刷新广告

java - Hibernate在列重命名后生成旧查询