简体   繁体   English

在Hibernate中使用session.flush()有什么用

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

When we are updating a record, we can use session.flush() with Hibernate. 当我们更新记录时,我们可以将session.flush()与Hibernate一起使用。 What's the need for flush() ? 什么是flush()需要什么?

Flushing the session forces Hibernate to synchronize the in-memory state of the Session with the database (ie to write changes to the database). 刷新会话会强制Hibernate将Session的内存中状态与数据库同步(即将更改写入数据库)。 By default, Hibernate will flush changes automatically for you: 默认情况下,Hibernate会自动为您更新更改:

  • 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,...). 允许显式刷新Session可以在某些情况下提供更精细的控制(分配ID,控制Session的大小,......)。

As rightly said in above answers, by calling flush() we force hibernate to execute the SQL commands on Database. 正如在上面的答案中正确地说,通过调用flush()我们强制hibernate在Database上执行SQL命令。 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之后和提交之前,如果直接访问DB(例如从SQL提示符)并检查修改的行,您将看不到更改。

This is same as opening 2 SQL command sessions. 这与打开2个SQL命令会话相同。 And changes done in 1 session are not visible to others until committed. 在提交之前,其他人在1个会话中完成的更改是不可见的。

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

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

You might use flush to force validation constraints to be realised and detected in a known place rather than when the transaction is committed. 您可以使用flush强制验证约束在已知位置实现和检测,而不是在提交事务时。 It may be that commit gets called implicitly by some framework logic, through declarative logic, the container, or by a template. 可能是某些框架逻辑通过声明性逻辑,容器或模板隐式调用commit In this case, any exception thrown may be difficult to catch and handle (it could be too high in the code). 在这种情况下,抛出的任何异常都可能难以捕获和处理(代码中可能太高)。

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. 但是,您必须在异常后回滚会话。

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. Hibernate save()可用于将实体保存到数据库。 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. 如果我们在没有事务的情况下使用它,并且我们在实体之间进行级联,那么除非我们刷新会话,否则只保存主实体。

flush(): Forces the session to flush. flush():强制会话刷新。 It is used to synchronize session data with database. 它用于将会话数据与数据库同步。

When you call session.flush(), the statements are executed in database but it will not committed. 当您调用session.flush()时,语句将在数据库中执行,但不会提交。 If you don't call session.flush() and if you call session.commit() , internally commit() method executes the statement and commits. 如果不调用session.flush(),并且调用session.commit(),则内部commit()方法执行语句并提交。

So commit()= flush+commit. 所以commit()= flush + commit。 So session.flush() just executes the statements in database (but not commits) and statements are NOT IN MEMORY anymore. 所以session.flush()只执行数据库中的语句(但不是提交),语句不再存在于内存中。 It just forces the session to 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会自动为您更新更改:在提交事务时执行某些查询之前允许显式刷新Session可以在某些情况下提供更精细的控制(获取ID,控制Session的大小) )

The flush() method causes Hibernate to flush the session. flush()方法使Hibernate刷新会话。 You can configure Hibernate to use flushing mode for the session by using setFlushMode() method. 您可以使用setFlushMode()方法将Hibernate配置为使用刷新模式进行会话。 To get the flush mode for the current session, you can use getFlushMode() method. 要获取当前会话的刷新模式,可以使用getFlushMode()方法。 To check, whether session is dirty, you can use isDirty() method. 要检查会话是否脏,可以使用isDirty()方法。 By default, Hibernate manages flushing of the sessions. 默认情况下,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 EntityManager and the Hibernate Session expose a set of methods, through which the application developer can change the persistent state of an entity. EntityManager和Hibernate Session公开了一组方法,应用程序开发人员可以通过这些方法更改实体的持久状态。

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 , UPDATE or DELETE statement. flush操作将每个实体状态更改并将其转换为INSERTUPDATEDELETE语句。

The flushing strategy is given by the flushMode of the current running Hibernate Session. 刷新策略由当前运行的Hibernate Session的flushMode给出。 Although JPA defines only two flushing strategies ( AUTO and COMMIT ), Hibernate has a much broader spectrum of flush types: 尽管JPA仅定义了两种刷新策略( AUTOCOMMIT ),但Hibernate具有更广泛的刷新类型:

  • ALWAYS : Flushes the Session before every query; ALWAYS :在每次查询之前刷新会话;
  • AUTO : This is the default mode and it flushes the Session only if necessary; AUTO :这是默认模式,只在必要时刷新Session;
  • COMMIT : The Session tries to delay the flush until the current Transaction is committed, although it might flush prematurely too; COMMIT :会话尝试延迟刷新,直到提交当前的Transaction,尽管它也可能过早刷新;
  • MANUAL : The Session flushing is delegated to the application, which must call Session.flush() explicitly in order to apply the persistence context changes. MANUAL :会话刷新被委托给应用程序,该应用程序必须显式调用Session.flush()才能应用持久性上下文更改。

By default, Hibernate uses the AUTO flush mode which triggers a flush in the following circumstances: 默认情况下,Hibernate使用AUTO刷新模式,在以下情况下触发刷新:

  • prior to committing a Transaction; 在进行交易之前;
  • prior to executing a JPQL/HQL query that overlaps with the queued entity actions; 在执行与排队实体操作重叠的JPQL / HQL查询之前;
  • before executing any native SQL query that has no registered synchronization. 在执行任何没有注册同步的本机SQL查询之前。

Calling EntityManager#flush does have side-effects . 调用EntityManager#flush确实有副作用 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. 它方便地用于具有生成的ID值(序列值)的实体类型:这样的ID仅在与底层持久层同步时可用。 If this ID is required before the current transaction ends (for logging purposes for instance), flushing the session is required. 如果在当前事务结束之前需要此ID(例如,为了记录日志),则需要刷新会话。

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语句来同步数据库的状态和会话的状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM