Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

How can I configure Hibernate to 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.

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.

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."

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?

like image 888
Derek Mahar Avatar asked Oct 15 '10 14:10

Derek Mahar


2 Answers

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

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_EAGER by turning their HibernateTemplate respectively HibernateInterceptor to that flush mode (source).

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

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.

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

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

Second, I personally see more drawbacks with immediate flushing than benefits, as explained black in white in the javadoc of 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).

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_FLUSH flushMode as a general setting (but maybe only for the specific operations that actually require eager, if any).

like image 91
Pascal Thivent Avatar answered Nov 07 '22 12:11

Pascal Thivent


Look in to autocommit though 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.

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

like image 31
Tony Ennis Avatar answered Nov 07 '22 12:11

Tony Ennis