How does session.flush help in releasing memory here?

As stated in the flush docs java

Flushing is the process of synchronizing the underlying persistent store with preserving the state stored in memory.

Here is my understanding of the above statement

So if someone does insert / update and then hide that the extra inserted rows will only lie in java memory. But conversely, the Db data will only be in sync with the persistent state held in memory only on commit.

Now let's get down to understanding

I came across HIbernate commit () and flush () where accepeted responds with session.flush helps in freeing memory in some cases and hence avoids OutOfMemoryException.

when i do below line1 (session.flush ()) will execute an insert query for 20 clients in the clients table, free up memory for 20 client objects in the list, but on the other hand creates 20 rows of client data under the clients table which is all are still in java memory (it will only go into the database when committed on line2). So I'm not sure how session.flush helps in freeing memory here?

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(); //line1
        session.clear();
    }
}

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

      

+3


source to share


2 answers


According to API session.flush ()

void flush()
           throws HibernateException

      

Forced session. Should be called at the end of one before executing the transaction and closing the session (depending on the flash mode, Transaction.commit () calls this method).

Flushing is the process of synchronizing the underlying persistent store with preserving the state stored in memory.

So the purpose of this method is to keep your persistent state in sync with the underlying database. It won't help free up memory if you still have object references.

Also refer to this link - Hibernate exception while processing a large collection of items

Where, as in your program, you create 100000

Customer

inside for-loop

. If there is no dormant code, then you do not maintain any references to these objects so that they are eligible for garbage collection.

But when you say the session.save(customer)

objects are associated with the Hibernate session, so they will be put into the first level cache.

If the number of objects increases and sufficient memory is not available then you will get rid of memory problems as hibernation tries to keep all of these objects in memory. Therefore, the method call flush

will force hibernate to make the required queries to the database, and the call clear

will help it free memory in the first level cache, thereby freeing some memory.

Update:



The call session.clear()

causes hibernate to clear memory that it internally maintains as a first-level cache. session.clear()

makes a call StatefulPersistenceContext.clear()

where it calls clear()

on different Maps
and other objects. This clears the memory in the first level cache. This clearly indicates that objects are eligible for garbage collection, which helps free up some memory. So the state is no longer maintained by Hibernate, so the objects are in detached state.

Now as API Traansaction.commit (); :

void commit()
            throws HibernateException

      

Clear the associated session and exit (unless we're in FlushMode.MANUAL.

This method will commit the underlying transaction if and only if the underlying transaction was initiated by this object.

The call commit()

removes all pending items and then posts commit

to the underlying database.

Update:



Also refer to this link - Session Flushing , which clearly states that JDBC calls are made when we call a method flush()

.

Sometimes the session executes the SQL statements required to synchronize the state of the JDBC connection with the state of the objects in memory. This process is called a flush.

Except when you explicitly hide (), there is no guarantee about when the session makes JDBC calls, only the order in which they are made.

+1


source


flush () will send data to the database. You will see that if you enable SQL logging in Hibernate. commit () commits changes previously pushed to the database. It may be that your cache stores some or all of this data. In this case, you need to tweak your cache setting.



That said, if you have so many changes or new objects in memory that you need to flash to avoid the OutOfmemoryError, chances are you need to redesign your design at a deeper level, such as doing multiple but smaller transactions. Having transactions this large can cause problems in both your application and the database.

0


source







All Articles