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
onsession
or onenityManager
? - Why
setFlushMode(FlushModeType.COMMIT);
increase in that way performance, and I cannot have same performance only by manually flushing entityManager?