Spring - Hibernate improve transaction performance with FlushMode
entitymanager, hibernate, java, spring, spring-data-jpa
Solution
The problem is that the default flush mode is `FlushModeType.AUTO`. In auto flush mode, Hibernate will flush before each query (only queries, not find operations). This means that in your above example, by default, Hibernate is flushing each time you call `getSingleResult()`. The reason it does this is because it's possible that the changes you have made would affect the results of your query and so Hibernate wants your query to be as accurate as possible and flushes first.
You don't see the performance hit in your first example because you are only issuing one query and scrolling through it. The best solution I have found is the one you mentioned which is just to set the flush mode to `COMMIT`. There should be no difference between calling `setFlushMode` on the `Session` or the `EntityManager`.
Problem
I'm trying to improve the performances of my asynk transactional method. In this task I have to read almost 7500 record from a table, elaborate it, and insert/update a corresponding row in another table. I'm using spring data jpa with hibernate. In order to get a `ScrollableResults` I inject the `EntityManager` into my service. Here how I get my `ScrollableResult` object: ``` Session session = (Session) em.unwrap(Session.class); ScrollableResults res = session.createQuery("from SourceTable s") .setCacheMode(CacheMode.IGNORE) .scroll(ScrollMode.FORWARD_ONLY); while (res.next()){ .... // em.flush() called every 40 cycles } ``` Cycling on result take about 60 seconds. And here the bottleneck. If inside my loop I execute a simple query: ``` query = em.createQuery("from DestTable d where d.item.id = :id", DestTable.class); while (res.next()){ query.setParameter("id", myId).getSingleResult(); } ``` The execution time become x10 slower.. and takes about 600s. I've tried to modify a parameter of my `Session` or of my `EntityManager`: `session.setFlushMode(FlushModeType.COMMIT);` `em.setFlushMode(FlushModeType.COMMIT);` It increase the performance and removing the manual flush() method the work is done in 40s!!! So my questions are: - What is the difference of call `setFlushMode` on `session` or on `enityManager`? - Why `setFlushMode(FlushModeType.COMMIT);` increase in that way performance, and I cannot have same performance only by manually flushing entityManager?