Search code examples
javahibernatejpaentitymanagerguice-persist

JPA & Guice-persist: permanently opened connection issue?


Using Hibernate, c3p0, Guice and Guice-persist, we have strange issues with the fact that the connections to the data are not released to the pool after transactions.

It seems that it's related to the way JpaPersistService is done, caching the EntityManager in a threadLocal variable:

private final ThreadLocal<EntityManager> entityManager = new ThreadLocal<EntityManager>();

My questions are:

  • Should we remove guice-persist and replace this by something creating a new entityManager then closing it each time we need (as suggested here) ?
  • Or caching the entityManager is the way to go, and we should fix our issues with something else ?

(Our issues: 1)mysql connection killed by mysqld after the classic 8h timeout, so the entityManager is no longer usable. Can be solved by enabling the c3p0 keep-alive, but as the application will sometime will not be used for a long time, we would like to avoid keeping useless active connection. 2) It seems that each EntityManager do some caching, and entites are not coherent between entityManager. Didn't looked at how to solve that)


Solution

  • Finally found a solution.

    It seems that it's a particular bug in guice-persist.

    If an EntityManager is injected outside an UnitOfWork or outisde a transaction, then an never-closing EntityManager is created, leading to strange issues.

    The documentation of guice-persist doesn't point this.

    The solution is to always inject Provider<EntityManager> instead of directly EntityManager if you're not inside a transaction or a UnitOfWork