we are developing an (JavaSE-) application which communicates to many clients via persistent tcp-connections. The client connects, performs some/many operations (which are updated to a SQL-Database) and closes the application / disconnects from server. We’re using Hibernate-JPA and manage the EntityManager-lifecycle on our own, using a ThreadLocal-variable. Actually we create a new EntityManager-instance on every client-request which works fine so far. Recently we profiled a bit and we found out that hibernate performs a SELECT-query to the DB before every UPDATE-statement. That is because our entities are in detached-state and every new EntityManager attaches the entity to the persistence context first. This leads to a massive SQL-overhead when the server is under load (because we have an write-heavy application)and we try to eliminate that leak.
- First, we thought about 2nd-Level-Cache. However, we discovered that hibernate invalidates it’s Query- and Collection-Caches whenever a new item is added or removed.
- On second thought, we evaluate whether to keep an EntityManager up as long as the client is logged in on the server. But I wonder if this is a “best practice”, because there are some drawbacks: thread-safety, managing-overhead of the EntityManager-instances, etc.
In short: we are looking for a way to get rid of those SELECT-statements before every UPDATE. Any ideas out there?
One possible way to get rid of
selectstatements when reattaching detached entities is to use Hibernate-specificupdate()operation instead ofmerge().update()unconditionally runs anupdateSQL statement and makes detached object persistent. If persistent object with the same identifier already exists in a session, it throws an exception. Thus, it’s a good choice when you are sure that:In JPA 2.0 you can access Hibernate-specific operations as follows:
See also: