Search code examples
javahibernatejpawildflyconnection-pooling

Wildfly connection pool exhausted on canceled HTTP requests


I have a Java EE application running on Wildfly 10 with RESTeasy and Hibernate. The application is pretty simple, it has entities, DAOs and resources:

@Entity
public class MyEntity {

    // ...

}

@Stateless
public class MyDAO {

    @PersistenceContext
    private EntityManager em;

    public List<MyEntity> list() {
        return this.em.createQuery("select e from MyEntity e", MyEntity.class).getResultList();
    }

}

@Path("/resource")
public class MyResource {

    @Inject
    private MyDAO dao;

    @GET
    public List<MyEntity> get() {
        return this.dao.list();
    }

}

So I do not use any JDBC connections directly, I delegate it all to JPA.

Problem is: no matter how many large my connection pool is, it eventually gets exhausted. Since datasource connections are handled in stateless beans, AFAIK connection opening/closing should be handled seamlessly.

Investigating on this connection leak, I've found out that I have many

ERROR [io.undertow.request] (default task-25) UT005023: Exception handling request to /resource: org.jboss.resteasy.spi.UnhandledException: RESTEASY003770: Response is committed, can't handle exception
...
Caused by: java.io.IOException: Broken pipe

exceptions, caused by canceled HTTP requests on the client side. Could these exceptions generate the connection leak? I hope not, since a client side action should not be able to exhaust the server connection pool.

Question is: may the problem be the canceled HTTP requests, how can I instruct Undertow/RESTeasy/Hibernate to handle that and exit cleanly? Where else could be the leak or how can I investigate to find out?

Update 1

[REMOVED]

Update 2

The last update (canceled HTTP requests) was misleading: further tests show how this happens in other cases, such as scheduled tasks (Java EE @Schedule) and event observers (Java EE @Observe).

The updated question is: when using JPA only to access the database, what could prevent a connection on being released?


Solution

  • Finally found out what it was: Java 8 parallel streams on lazy collections. Simply don't use parallel streams for collections of JPA relationships, since it may use multiple connection from the pool during stream processing but on collecting the results only one connection is returned to the pool while the others fails with an attempt to return the same connection twice, eventually exhausting the pool.