Java Hibernate中session.flush()有什么用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3220336/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 17:31:12  来源:igfitidea点击:

What's the use of session.flush() in Hibernate

javahibernateorm

提问by CHANTI

When we are updating a record, we can use session.flush()with Hibernate. What's the need for flush()?

当我们更新记录时,我们可以session.flush()与 Hibernate 一起使用。有什么需要flush()

回答by miku

Flushing the Session gets the data that is currently in the session synchronized with what is in the database.

刷新会话会获取当前会话中的数据与数据库中的数据同步。

More on the Hibernate website:

更多关于 Hibernate 网站的信息:

flush()is useful, because there are absolutely no guarantees about when the Session executes the JDBC calls, only the order in which they are executed - except you use flush().

flush()很有用,因为绝对不能保证 Session 何时执行 JDBC 调用,只能保证它们的执行顺序 - 除了您使用flush().

回答by Pascal Thivent

Flushing the session forces Hibernate to synchronize the in-memory state of the Sessionwith the database (i.e. to write changes to the database). By default, Hibernate will flush changes automatically for you:

刷新会话会强制 Hibernate 将 的内存状态Session与数据库同步(即,将更改写入数据库)。默认情况下,Hibernate 会自动为您刷新更改:

  • before some query executions
  • when a transaction is committed
  • 在一些查询执行之前
  • 当一个事务被提交时

Allowing to explicitly flush the Sessiongives finer control that may be required in some circumstances (to get an ID assigned, to control the size of the Session,...).

允许显式刷新Session在某些情况下可能需要更精细的控制(以获得分配的 ID,控制会话的大小,...)。

回答by Kaushik Lele

As rightly said in above answers, by calling flush()we force hibernate to execute the SQL commands on Database. But do understand that changes are not "committed" yet. So after doing flush and before doing commit, if you access DB directly (say from SQL prompt) and check the modified rows, you will NOT see the changes.

正如在上面的答案中正确地说的那样,通过调用flush()我们强制休眠在数据库上执行 SQL 命令。但是请理解更改尚未“提交”。因此,在执行刷新之后和执行提交之前,如果您直接访问数据库(例如从 SQL 提示)并检查修改后的行,您将不会看到更改。

This is same as opening 2 SQL command sessions. And changes done in 1 session are not visible to others until committed.

这与打开 2 个 SQL 命令会话相同。并且在 1 个会话中完成的更改在提交之前对其他人不可见。

回答by Shoaib Chikate

I only know that when we call session.flush()our statements are execute in database but not committed.

我只知道当我们调用时,我们session.flush()的语句在数据库中执行但未提交。

Suppose we don't call flush()method on session object and if we call commit method it will internally do the work of executing statements on the database and then committing.

假设我们不在flush()会话对象上调用方法,如果我们调用 commit 方法,它将在内部完成在数据库上执行语句然后提交的工作。

commit=flush+commit(in case of functionality)

commit=flush+commit(在功能的情况下)

Thus, I conclude that when we call method flush() on Session object, then it doesn't get commit but hits the database and executes the query and gets rollback too.

因此,我得出的结论是,当我们在 Session 对象上调用方法 flush() 时,它不会提交,而是命中数据库并执行查询并回滚。

In order to commit we use commit() on Transaction object.

为了提交,我们在 Transaction 对象上使用 commit()。

回答by rghome

You might use flushto force validation constraints to be realised and detected in a known place rather than when the transaction is committed. It may be that commitgets called implicitly by some framework logic, through declarative logic, the container, or by a template. In this case, any exception thrown may be difficult to catch and handle (it could be too high in the code).

您可能会使用flush强制在已知位置而不是在提交事务时实现和检测验证约束。它可能会commit被某些框架逻辑、声明性逻辑、容器或模板隐式调用。在这种情况下,抛出的任何异常都可能难以捕获和处理(代码中的异常可能太高)。

For example, if you save()a new EmailAddress object, which has a unique constraint on the address, you won't get an error until you commit.

例如,如果您创建save()了一个对地址具有唯一约束的新 EmailAddress 对象,则在提交之前您不会收到错误消息。

Calling flush()forces the row to be inserted, throwing an Exception if there is a duplicate.

调用flush()强制插入行,如果有重复则抛出异常。

However, you will have to roll back the session after the exception.

但是,您必须在异常发生后回滚会话。

回答by johanwannheden

Calling EntityManager#flushdoes have side-effects. It is conveniently used for entity types with generated ID values (sequence values): such an ID is available only upon synchronization with underlying persistence layer. If this ID is required before the current transaction ends (for logging purposes for instance), flushing the session is required.

调用EntityManager#flush确实有副作用。它很方便地用于具有生成的 ID 值(序列值)的实体类型:这样的 ID 仅在与底层持久层同步时才可用。如果在当前事务结束之前需要此 ID(例如用于日志记录),则需要刷新会话。

回答by Sundar Gsv

I would just like to club all the answers given above and also relate Flush() method with Session.save() so as to give more importance

我只想把上面给出的所有答案都放在一起,并将 Flush() 方法与 Session.save() 联系起来,以便给予更多的重视

Hibernate save() can be used to save entity to database. We can invoke this method outside a transaction, that's why I don't like this method to save data. If we use this without transaction and we have cascading between entities, then only the primary entity gets saved unless we flush the session.

Hibernate save() 可用于将实体保存到数据库。我们可以在事务之外调用这个方法,这就是为什么我不喜欢这个方法来保存数据。如果我们在没有事务的情况下使用它并且我们在实体之间进行级联,那么除非我们刷新会话,否则只会保存主要实体。

flush(): Forces the session to flush. It is used to synchronize session data with database.

flush():强制会话刷新。它用于将会话数据与数据库同步。

When you call session.flush(), the statements are executed in database but it will not committed. If you don't call session.flush() and if you call session.commit() , internally commit() method executes the statement and commits.

当您调用 session.flush() 时,语句在数据库中执行但不会提交。如果不调用 session.flush() 而调用 session.commit() ,则内部 commit() 方法执行语句并提交。

So commit()= flush+commit. So session.flush() just executes the statements in database (but not commits) and statements are NOT IN MEMORY anymore. It just forces the session to flush.

所以 commit()=flush+commit。所以 session.flush() 只是执行数据库中的语句(但不提交)并且语句不再在内存中。它只是强制会话刷新。

Few important points:

几个重要的点:

We should avoid save outside transaction boundary, otherwise mapped entities will not be saved causing data inconsistency. It's very normal to forget flushing the session because it doesn't throw any exception or warnings. By default, Hibernate will flush changes automatically for you: before some query executions when a transaction is committed Allowing to explicitly flush the Session gives finer control that may be required in some circumstances (to get an ID assigned, to control the size of the Session)

我们应该避免在事务边界之外保存,否则将不会保存映射的实体,从而导致数据不一致。忘记刷新会话是很正常的,因为它不会抛出任何异常或警告。默认情况下,Hibernate 将自动为您刷新更改:在提交事务时执行某些查询之前允许显式刷新会话提供在某些情况下可能需要的更好的控制(以获得分配的 ID,控制会话的大小)

回答by Sundar Gsv

The flush()method causes Hibernate to flush the session. You can configure Hibernate to use flushing mode for the session by using setFlushMode()method. To get the flush mode for the current session, you can use getFlushMode()method. To check, whether session is dirty, you can use isDirty()method. By default, Hibernate manages flushing of the sessions.

flush()方法使 Hibernate 刷新会话。您可以通过 usingsetFlushMode()方法将 Hibernate 配置为对会话使用刷新模式。要获取当前会话的刷新模式,您可以使用getFlushMode()方法。要检查会话是否脏,您可以使用isDirty()方法。默认情况下,Hibernate 管理会话的刷新。

As stated in the documentation:

如文档中所述:

https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/flushing/Flushing.html

https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/flushing/Flushing.html

Flushing

Flushing is the process of synchronizing the state of the persistence context with the underlying database. The EntityManagerand the Hibernate Sessionexpose a set of methods, through which the application developer can change the persistent state of an entity.

The persistence context acts as a transactional write-behind cache, queuing any entity state change. Like any write-behind cache, changes are first applied in-memory and synchronized with the database during flush time. The flush operation takes every entity state change and translates it to an INSERT, UPDATEor DELETEstatement.

The flushing strategy is given by the flushModeof the current running Hibernate Session. Although JPA defines only two flushing strategies (AUTOand COMMIT), Hibernate has a much broader spectrum of flush types:

  • ALWAYS: Flushes the Session before every query;
  • AUTO: This is the default mode and it flushes the Session only if necessary;
  • COMMIT: The Session tries to delay the flush until the current Transaction is committed, although it might flush prematurely too;
  • MANUAL: The Session flushing is delegated to the application, which must call Session.flush()explicitly in order to apply the persistence context changes.

By default, Hibernate uses the AUTOflush mode which triggers a flush in the following circumstances:

  • prior to committing a Transaction;
  • prior to executing a JPQL/HQL query that overlaps with the queued entity actions;
  • before executing any native SQL query that has no registered synchronization.

冲洗

刷新是将持久化上下文的状态与底层数据库同步的过程。的EntityManager和休眠Session暴露了一组方法,通过该应用程序开发者可改变的实体的持久状态。

持久性上下文充当事务性后写缓存,将任何实体状态更改排队。与任何后写缓存一样,更改首先在内存中应用,并在刷新期间与数据库同步。刷新操作获取每个实体状态更改并将其转换为INSERT, UPDATEorDELETE语句。

刷新策略由当前运行的 Hibernate Session的flushMode给出。尽管 JPA 只定义了两种刷新策略(AUTOCOMMIT),但 Hibernate 具有更广泛的刷新类型:

  • ALWAYS: 在每次查询之前刷新会话;
  • AUTO:这是默认模式,仅在必要时刷新会话;
  • COMMIT: Session 尝试延迟刷新直到当前事务提交,尽管它也可能过早刷新;
  • MANUAL:会话刷新被委托给应用程序,它必须Session.flush()显式调用才能应用持久性上下文更改。

默认情况下,Hibernate 使用AUTO刷新模式,在以下情况下触发刷新:

  • 在提交交易之前;
  • 在执行与排队实体操作重叠的 JPQL/HQL 查询之前;
  • 在执行任何没有注册同步的本机 SQL 查询之前。

回答by lennoxGER

With this method you evoke the flush process. This process synchronizes the state of your database with state of your session by detecting state changes and executing the respective SQL statements.

使用这种方法,您可以唤起冲洗过程。此过程通过检测状态更改并执行相应的 SQL 语句,将数据库状态与会话状态同步。