What's the Use of Session.Flush() in Hibernate

Why we need flush in hibernate?

Forces the session to 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.

If you dont call session.flush() and if you call session.commit() , internally commit() method executes the statement and commits.

So commit()= flush+commit.

So seesion.flush() just executes the statements in database (but not commits) and statements are NOT IN MEMORY anymore. It just forces the session to flush.

Flush mainly used when you are dealing with thousands and millions of records.
So while dealing with such number of records we use batch update and flush.

Session session = SessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Employee emp = new Employee(.....);
session.save(emp);
}
tx.commit();
session.close();

In above example if you do not call flush it may throw OutOfMemoryError.

You can check out this post about flushing

Hibernate: flush() and commit()

In the Hibernate Manual you can see this example

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

for (int i = 0; i < 100000; i++) {
Customer customer = new Customer(...);
session.save(customer);
if (i % 20 == 0) { // 20, same as the JDBC batch size
// flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}

tx.commit();
session.close();

Without the call to the flush method, your first-level cache would throw an OutOfMemoryException

Also you can look at this post about flushing

How does session.clear() work in Hibernate

Think of the Session as a cache of entities you have already loaded from (or persisted to) the database since you've started the current transaction.

  1. Session.clear is not mandatory in any way, but is useful if you do a lot of entity loading/saving within one transaction, to avoid getting out of memory error. In your example, you'll have 50 employee entities replicated in the session. Without the flush and clear method call every 50 save() you would have had 100.000 entities replicated in the session (and not garbage collectable, because the session has a link to the entity).

  2. Session.clear will not perform commit nor rollback. Not even a flush (hence why you should do flush before a Session.clear, so that hibernate generates sql queries for pending entities updates.

  3. Rollback or commit actions are not performed on the application side, but in the database : hibernate will just ask the database to commit or rollback (Hibernate might trigger a flush before the commit action, but the flush is not part of the commit). The commit action will not (and can't) access the session. It is an database internal mechanism that will persist (or revert) the data modification performed thanks to all SQL queries run since the start of the transaction.

Exactly in the same way, opening a transaction in hibernate is not performing a lot of things : mainly getting a db connection out of the pool, and telling the database to NOT auto_commit following sql queries but to wait for a commit or rollback command.

Question about Hibernate session.flush()

From the javadoc of Session#flush:

Force this session to flush. Must be
called at the end of a unit of work,
before committing the transaction and
closing the session (depending on
flush-mode, Transaction.commit()
calls this method).

Flushing is the process of synchronizing the underlying
persistent store with persistable
state held in memory.

In other words, flush tells Hibernate to execute the SQL statements needed to synchronize the JDBC connection's state with the state of objects held in the session-level cache. And the condition if (i % 20 == 0) will make it happen for every i multiple of 20.

But, still, the new Car instances will be held in the session-level cache and, for big myList.size(), you're going to eat all memory and ultimately get an OutOfMemoryException. To avoid this situation, the pattern described in the documentation is to flush AND clear the session at regular intervals (same size as the JDBC batch size) to persist the changes and then detach the instances so that they can be garbage collected:

13.1. Batch inserts


When making new objects persistent
flush() and then clear() the session
regularly in order to control the size
of the first-level cache.

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
session.save(customer);
if ( i % 20 == 0 ) { //20, same as the JDBC batch size
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}

tx.commit();
session.close();

The documentation mentions in the same chapter how to set the JDBC batch size.

See also

  • 10.10. Flushing the Session
  • Chapter 13. Batch processing

Hibernate session.flush() even though autocommit is set

Autocommit and session.flush() are two different things:

  1. Autocommit sets the autocommit mode on the underlying JDBC transaction. It basically means that every SQL statement (SELECT, UPDATE, INSERT, DELETE, ...) is executed in its own transaction.
  2. session.flush() tells Hibernate to synchronize the in-memory state with the database, so to write SQL statements to the JDBC connection. See more here: What's the use of session.flush() in Hibernate

So while I do not know why entities in your example only get persisted to the database in one case, it likely has nothing to do with the autocommit mode.

Why is it necessary to call session.flush() after session.delete() in Hibernate?

When your work with database via Hibernate you are using Hibernate session. Hibernate sessions flushed to the database by following three situations.

  1. commit()- When you commit a transaction
  2. Before you run a query
  3. When you call session.flush()

Here the most important is second. After every query does not Hibernate session flush database. If we run Native SQL Query via Hibernate,Hibernate does not know to flush the session or also if run HQL also Hibernate does not know to flush session. The call to flush will synchronise the session state with the database.

See the following:
Hibernate flush before delete and Flushing the Session



Related Topics



Leave a reply



Submit