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

发布于 2024-09-27 02:18:18 字数 866 浏览 8 评论 0原文

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

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

来自文档:

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

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

小代码示例:

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

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

  • 的一些查询执行之前
  • 是在org.hibernate.Transaction.commit()
  • 和 Session.flush()

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

挽你眉间 2024-10-04 02:18:18

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

不,不会,您应该使用边界明确的事务。引用非事务性数据访问和自动提交模式

使用 Hibernate 以非事务方式工作

看下面的代码,
访问数据库,无需
交易边界:

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

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

  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 对象是
关闭并且资源返回到
游泳池。

显然,这对于
你已经执行的 SELECT,但是看看
在这种变化中:

Session session = getSessionFactory().openSession(); 
Long generatedId = session.save(item); 
会话.关闭(); 

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

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

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.

我乃一代侩神 2024-10-04 02:18:18

关闭会话将始终将所有工作刷新到数据库。当发生更改并且您正在查询包含更改记录的表时,Flushmode.AUTO 将工作刷新到数据库。

closing a session will always flush al work to the database. Flushmode.AUTO flushes work to the database when there are changes and you are quering the table with changed records.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文