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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3943366/
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-10-30 04:04:19  来源:igfitidea点击:

How can I configure Hibernate to immediately apply all saves, updates, and deletes?

javadatabasehibernate

提问by Derek Mahar

How can I configure Hibernateto apply all saves, updates, and deletes to the database server immediately after the session executes each operation? By default, Hibernate enqueues all save, update, and delete operations and submits them to the database server only after a flush()operation, committing the transaction, or the closing of the session in which these operations occur.

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

One benefit of immediately flushing database "write" operations is that a program can catch and handle any database exceptions (such as a ConstraintViolationException) in the code block in which they occur. With late or auto-flushing, these exceptions may occur long after the corresponding Hibernate operation that caused the SQL operation.

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

Update:

更新:

According to the Hibernate API documentation for interface Session, the benefit of catching and handling a database exception before the session ends may be of no benefit at all: "If the Session throws an exception, the transaction must be rolled back and the session discarded. The internal state of the Session might not be consistent with the database after the exception occurs."

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

Perhaps, then, the benefit of surrounding an "immediate" Hibernate session write operation with a try-catch block is to catch and log the exception as soon as it occurs. Does immediate flushing of these operations have any other benefits?

那么,也许,用 try-catch 块包围“立即”Hibernate 会话写入操作的好处是在异常发生时立即捕获并记录异常。立即冲洗这些操作还有其他好处吗?

回答by Pascal Thivent

How can I configure Hibernate to apply all saves, updates, and deletes to the database server immediately after the session executes each operation?

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

To my knowledge, Hibernate doesn't offer any facility for that. However, it looks like Spring does and you can have some data access operations FLUSH_EAGERby turning their HibernateTemplaterespectively HibernateInterceptorto that flush mode(source).

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

But I warmly suggest to read the javadoc carefully(I'll come back on this).

但我强烈建议仔细阅读 javadoc (我会回来讨论这个)。

By default, Hibernate enqueues all save, update, and delete operations and submits them to the database server only after a flush() operation, committing the transaction, or the closing of the session in which these operations occur.

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

Closing the session doesn't flush.

关闭会话不会刷新。

One benefit of immediately flushing database "write" operations is that a program can catch and handle any database exceptions (such as a ConstraintViolationException) in the code block in which they occur. With late or auto-flushing, these exceptions may occur long after the corresponding Hibernate operation that caused the SQL operation

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

First, DBMSs vary as to whether a constraint violation comes back on the insert (or update ) or on the subsequent commit (this is known as immediate or deferred constraints). So there is no guarantee and your DBA might even not want immediate constraints (which should be the default behavior though).

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

Second, I personally see more drawbacks with immediate flushing than benefits, as explained black in white in the javadoc of FLUSH_EAGER:

其次,我个人认为立即冲洗的弊端多于好处,正如 javadoc 中的 black in white 所解释的FLUSH_EAGER

Eager flushing leads to immediate synchronization with the database, even if in a transaction. This causes inconsistencies to show up and throw a respective exception immediately, and JDBC access code that participates in the same transaction will see the changes as the database is already aware of them then. But the drawbacks are:

  • additional communication roundtrips with the database, instead of a single batch at transaction commit;
  • the fact that an actual database rollback is needed if the Hibernate transaction rolls back (due to already submitted SQL statements).

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

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

And believe me, increasing the database roundtrips and loosing the batching of statements can cause major performance degradation.

相信我,增加数据库往返次数和丢失语句批处理会导致严重的性能下降

Also keep in mind that once you get an exception, there is not much you can do apart from throwing your session away.

还要记住,一旦遇到异常,除了丢弃会话之外,您无能为力。

To sum up, I'm very happy that Hibernate enqueues the various actions and I would certainly not use this EAGER_FLUSHflushModeas a general setting (but maybe only for the specific operations that actually require eager, if any).

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

回答by Tony Ennis

Look in to autocommitthough it is not recommended. If your work includes more than one update or insert SQL statement, you autocommit some of the work, and then a statement fails, you have a potentially arduous task of undoing the first part of the action. It gets really fun when the 'undo' operation fails.

autocommit尽管不推荐,但请查看。如果您的工作包括多个更新或插入 SQL 语句,您会自动提交一些工作,然后一条语句失败,那么您将面临撤消操作的第一部分的潜在艰巨任务。当“撤消”操作失败时,这真的很有趣。

Anyway, here's a link that shows how to do it.

无论如何,这是一个显示如何操作的链接