在更新记录时,我们可以使用Hibernate中的session.flush()
。那么flush()
的作用是什么?
刷新session会强制Hibernate将Session
中的内存状态与数据库同步(即将更改写入数据库)。 默认情况下,Hibernate会自动为您刷新更改:
允许显式刷新Session
提供了更精细的控制,这在某些情况下可能是必需的(例如获取ID分配、控制Session的大小等)。
正如以上答案中所说的那样,通过调用flush()
,我们可以强制Hibernate在数据库上执行SQL命令。但请注意,更改尚未“提交”。
因此,在执行commit
之前执行flush()
并直接访问数据库(例如从SQL提示符)并检查修改后的行时,您将不会看到更改。
这与打开两个SQL命令会话相同。只有在提交更改后,其他会话才能看到已经完成的更改。
我只知道当我们调用session.flush()
时,语句会在数据库中执行但不被提交。
假设我们不在session对象上调用flush()
方法,而是在调用commit方法时,它会在内部执行将语句提交到数据库然后进行提交的工作。
commit=flush+commit
(在功能方面)
因此,我得出结论,当我们在Session对象上调用flush()方法时,它不会被提交,但会在数据库中执行查询并发生回滚。
为了提交,我们使用Transaction对象上的commit()方法。
刷新会话可以使当前会话中的数据与数据库中的数据同步。
更多信息请参阅Hibernate网站:
flush()
很有用,因为没有任何保证会话何时执行JDBC调用,只有它们执行的顺序 - 除非您使用flush()
。
flush
强制执行验证约束条件,以在已知位置进行检测,而不是在事务提交时进行检测。也许某些框架逻辑、声明性逻辑、容器或模板隐式调用了commit
。在这种情况下,任何抛出的异常可能很难捕获和处理(它可能太高在代码中)。flush()
将强制插入行,如果有重复则抛出异常。flush()
方法会导致Hibernate刷新会话。您可以使用setFlushMode()
方法为会话配置刷新模式。要获取当前会话的刷新模式,可以使用getFlushMode()
方法。要检查会话是否已更改,请使用isDirty()
方法。默认情况下,Hibernate管理会话的刷新。根据文档所述:https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/flushing/Flushing.html
刷新
刷新是将持久化上下文的状态与底层数据库同步的过程。通过
EntityManager
和HibernateSession
,应用程序开发人员可以通过一组方法更改实体的持久状态。持久化上下文充当一个事务性的写后缓存,排队任何实体状态更改。像任何写后缓存一样,更改首先在内存中应用,然后在刷新时间与数据库同步。刷新操作将每个实体状态更改转换为
INSERT
、UPDATE
或DELETE
语句。刷新策略由当前运行的Hibernate Session的flushMode给出。尽管JPA仅定义了两种刷新策略(
AUTO
和COMMIT
),但Hibernate具有更广泛的刷新类型:
ALWAYS
:在每个查询之前刷新Session;AUTO
:这是默认模式,仅在必要时刷新Session;COMMIT
:Session尝试延迟刷新直到当前事务提交,尽管它也可能过早地刷新;MANUAL
:Session的刷新被委托给应用程序,应用程序必须显式调用Session.flush()
来应用持久化上下文更改。默认情况下,Hibernate使用
AUTO
刷新模式,在以下情况下触发刷新:
- 在提交事务之前;
- 在执行与排队实体操作重叠的JPQL/HQL查询之前;
- 在执行任何没有注册同步的本机SQL查询之前。
调用EntityManager#flush
会有副作用。它方便地用于具有生成的ID值(序列值)的实体类型:这样的ID仅在与底层持久性层同步后才可用。如果需要在当前事务结束之前获取此ID(例如用于日志记录),则需要刷新会话。
id = session.save(obj);
保存对象时,事务在下一行被提交,但是obj没有保存到数据库中,为什么?2)我使用session.save(obj);
保存了obj,并在返回时使用return obj.getprimaryID();
,在这种情况下,obj已保存到数据库中。那么为什么会出现这种行为? - Amogh