I use Java 8, Hibernate 5.1.0.Final and Guice 4.1.0.
@Inject
private Provider<ExampleDAO> exampleDAOProvider;
public void test(){
ExecutorService threadPool = Executors.newFixedThreadPool(10);
for (int i = 0; i < 100; i++)
threadPool.execute(new Runnable() {
@Override
public void run() {
logger.info(exampleDAOProvider.find(1l));
}
});
threadPool.shutdown();
}
Every test()
method execution will produce 10 (thread pool size) rows more in pg_stat_activity
. They are simple select * from
queries which have idle in transaction
state and never disappear. So I reach hibernate.c3p0.max_size
limit and my application stops working with database.
Database module:
public class ExampleModule extends PrivateModule {
@Override
public void configure() {
install(new JpaPersistModule("example-persistence-unit").properties(jpaProperties()));
bind(ExampleDAO.class).to(ExampleDAOImpl.class);
expose(ExampleDAO.class);
Key<PersistFilter> key = Key.get(PersistFilter.class, ExamplePersistenceUnit.class);
bind(key).to(PersistFilter.class);
expose(key);
}
}
I have tried to @Inject Provider<ExampleDAO> exampleDAOProvider
into the task class code but it does not change anything. If I @Inject exampleDAO
, then I face concurrency issues (ConcurrentModificationException
) because it uses the same EntityManager
.
If I use @Inject Provider<ExampleDAO> exampleDAOProvider
or direct @Inject ExampleDAO exampleDAO
without multithreading, it works well and connections get released.
Why does it happen? How to get connections released in the multithreaded code?