I have a long running (but rather simple) application that uses Hibernate (via JPA). It was experiencing rather dramatic slowdown as it ran. I've been able to narrow down to requiring an occasional entityManager.clear() call. When Hibernate's entity manager is tracking 100,000 entities, it is ~100x slower than when it is tracking only a few (see results below). My question is: why does Hiberate slow down so much when it is tracking a lot of entities? And are there any other ways around it?


!!! Update: I've been able to narrow this down to Hibernate's auto-flushing code. !!!

Specifically to org.hibernate.event.internal.AbstractFlushingEventListener's flushEntities() method (at least in Hibernate 4.1.1.Final). In it there is a loop that iterates over ALL entities in the persistence context, performing some extensive checks around flushing each of them (even though all the entities are already flushed in my example!).

So partially answering the second part of my question, the performance problem can be addressed by setting the flush mode to FlushModeType.COMMIT on the query (see updated results below). e.g.

Place place = em.createQuery("from Place where name = :name", Place.class)
    .setParameter("name", name)
    .setFlushMode(FlushModeType.COMMIT)  // <-- yay!
    .getSingleResult();

... but this seems like a rather ugly solution--passing the responsibility for knowing if things are flushed to the query methods instead of keeping it in the updating methods. It also pretty much means that I either have to set flush mode to COMMIT on all query methods, or, more likely, set it on the EntityManager.

This makes me wonder: is this expected behavior? Am I doing something wrong with flushing or how I define entities? Or is this

Edit
Report