如何配置Hibernate以立即应用所有保存,更新和删除?

如何配置Hibernate在会话执行每个操作后立即将所有保存,更新和删除应用到数据库服务器? 默认情况下,Hibernate将所有保存,更新和删除操作排入队列,并仅在执行flush()操作,提交事务或关闭发生这些操作的会话之后将它们提交到数据库服务器。

立即刷新数据库“写”操作的一个好处是程序可以捕获并处理它们出现的代码块中的任何数据库exception(例如ConstraintViolationException )。 对于延迟或自动刷新,这些exception可能在导致SQL操作的相应Hibernate操作之后很久发生。

更新:

根据接口Session的Hibernate API文档,在会话结束之前捕获和处理数据库exception的好处可能完全没有任何好处:“如果会话抛出exception,则必须回滚事务并丢弃会话。exception发生后,Session的内部状态可能与数据库不一致。“

那么,使用try-catch块围绕“立即”Hibernate会话写操作的好处可能是在exception发生时立即捕获并记录exception。 立即冲洗这些操作是否还有其他好处?

如何配置Hibernate在会话执行每个操作后立即将所有保存,更新和删除应用到数据库服务器?

据我所知,Hibernate没有为此提供任何便利。 但是,它看起来像Spring,你可以通过将HibernateTemplate分别转换为刷新模式 ( 源 ) 来进行一些数据访问操作FLUSH_EAGER

但我热烈建议仔细阅读javadoc(我会再回过头来看看)。

默认情况下,Hibernate将所有保存,更新和删除操作排入队列,并仅在执行flush()操作,提交事务或关闭发生这些操作的会话之后将它们提交到数据库服务器。

关闭会话不会刷新。

立即刷新数据库“写”操作的一个好处是程序可以捕获并处理它们出现的代码块中的任何数据库exception(例如ConstraintViolationException)。 对于延迟或自动刷新,这些exception可能在导致SQL操作的相应Hibernate操作之后很久发生

首先,DBMS在插入(或更新)或后续提交(这称为立即或延迟约束 )上是否返回约束时会有所不同。 因此无法保证您的DBA甚至可能不需要立即约束(尽管应该是默认行为)。

其次,我个人看到更多的缺点,立即冲洗而不是好处,正如FLUSH_EAGER的javadoc中的白色黑色解释:

即使在事务中,急切刷新也会导致与数据库立即同步。 这会导致出现不一致并立即抛出相应的exception,参与同一事务的JDBC访问代码将看到更改,因为数据库已经知道它们。 但缺点是:

  • 与数据库进行额外的通信往返,而不是在事务提交时进行单个批处理;
  • 如果Hibernate事务回滚(由于已经提交的SQL语句),则需要实际的数据库回滚。

并且相信我,增加数据库往返并丢失语句的批处理可能会导致性能大幅下降

另外请记住,一旦你得到一个例外,除了扔你的会话之外你没有什么可做的。

总而言之,我很高兴Hibernate将各种操作排入队列,我肯定不会将此EAGER_FLUSH flushMode用作一般设置(但可能仅适用于实际需要的特定操作,如果有的话)。

尽管不推荐,但请注意autocommit 。 如果您的工作包含多个更新或插入SQL语句,您自动提交一些工作,然后语句失败,您可能需要撤消操作的第一部分。 当“撤消”操作失败时,它变得非常有趣。

无论如何, 这是一个链接,显示如何做到这一点 。