I have the problem that I need to run multiple task in parallel.
For this purpose I am using Futures.
One of this tasks is a simple select on a postgres database via hibernate, the problem is that every time this task gets executed a new postgres connection get created an soon postgres does not accept any more connections.
The application runs on a tomcat-server and uses connection pooling.
If i execute the task not in a different thread it works fine.
This is the method that uses hibernate:
@Override
public Future<MonitoringResult> performMonitoringAction()  {
    return getExecutorService().submit(() -> {
        long milliseconds = System.currentTimeMillis();
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtil.getCurrentInstance().newSession();
            tx = session.beginTransaction();
            List<Entity> sle = (List<Entity>) session.createQuery("from Entity").list();
            return new MonitoringResult(System.currentTimeMillis() - milliseconds, true);
        } catch (Exception e) {
            return new ExceptionMonitoringResult(System.currentTimeMillis() - milliseconds, e);
        } finally {
            if (tx != null) {
                tx.commit();
        }
            if (session != null) {
                session.close();
            }
        }
    });
}
This is how it gets called:
public Response all() {
    List<Future<MonitoringResult>> runningMonitorTasks = new ArrayList<>(monitoredServices.length);
    // start all monitoring services
    for (MonitorableService monitoredService : monitoredServices) {
        runningMonitorTasks.add(monitoredService.performMonitoringAction());
    }
    HashMap<String, MonitoringResult> resultMap = new HashMap();
    // collect results of monitoring services
    for (int i = 0; i < monitoredServices.length; i++) {
        MonitorableService monitoredService = monitoredServices[i];
        Future<MonitoringResult> runningTask = runningMonitorTasks.get(i);
        MonitoringResult result;
        try {
            result = runningTask.get(60, TimeUnit.SECONDS); // wait till task is finished
        } catch (TimeoutException | InterruptedException | ExecutionException ex) {
            LOGGER.log(Level.SEVERE, "Monitoring task failed", ex);
            result = new ExceptionMonitoringResult(-1, ex);
        }
        logIfUnreachable(result, monitoredService);
        resultMap.put(monitoredService.getServiceName(), result);
    }
    return Response.ok(resultMap).build();
}
Called this way it works fine:
public Response all() {
    HashMap<String, MonitoringResult> resultMap = new HashMap();
    // execute monitoring services
    for (MonitorableService monitoredService : monitoredServices) {
        Future<MonitoringResult> result = monitoredService.performMonitoringAction();
        MonitoringResult get;
        try {
            get = result.get();
            logIfUnreachable(get, monitoredService);
        } catch (InterruptedException | ExecutionException ex) {
            Logger.getLogger(RestMonitorService.class.getName()).log(Level.SEVERE, null, ex);
            get = new ExceptionMonitoringResult(-1, ex);
        }
        resultMap.put(monitoredService.getServiceName(), get);
    }
    return Response.ok(resultMap).build();
}
HibernateUtil class:
public class HibernateUtil implements ServletContextListener {
    private static HibernateUtil currentInstance;
    private SessionFactory sessionFactory;
    private ServletContext servletContext;
    private final Log logger = LogFactory.getLog(LoginInfo.class);
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        // set current instance
        currentInstance = this;
        Configuration cfg = new Configuration().configure();
        StandardServiceRegistryBuilder builder = new    StandardServiceRegistryBuilder().applySettings(
                cfg.getProperties());
        sessionFactory = cfg.buildSessionFactory(builder.build());
        servletContext = sce.getServletContext();
    }
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // close session factory
        if(sessionFactory!=null){
            sessionFactory.close();
        }
        sessionFactory = null;
    }
    public static HibernateUtil getCurrentInstance() {
        return currentInstance;
    }
    public Session newSession() {
        return sessionFactory.openSession();
    }
}
 
    