Configurando Pool de Conexão com JPA
Autor: Rodrigo Fortes | Publicado: 2015-11-24T11:49:00-02:00



Aplicações pequenas podem não precisar de um pool de conexões, porém aplicações maiores, o pool pode se fazer necessário, pois a
cada conexão com o banco é aberto uma conexão no início da transação e fechada
ao final, isto pode tornar sua aplicação inutilizável dependendo do número de
requisições.







“Mas o que faz o pool? Basicamente,
mantém um certo número de conexões abertas com o
banco de dados. Quando o cliente Java abre uma conexão usando o pool, ao invés
de abrir uma nova conexão com o banco usando o&nbsp;driver&nbsp;JDBC, este
simplesmente pega uma das conexões já aberta com o banco e a marca como alocada
para aquele cliente Java.







O cliente Java então usa a conexão normalmente e
faz as operações desejadas no banco. Quando o cliente fecha a conexão usando o
pool, este não fecha a conexão com o banco. Ao invés disso, mantém a mesma
aberta, mas a marca como disponível.







Quando o número de conexões que os clientes abrem
usando o pool passa do número de conexões que o connection pool mantém abertas,
o pool abre uma nova conexão com o banco de dados, a não ser que tenha atingido
um número máximo de conexões reais, caso no qual seria lançada uma exceção.” (http://www.devmedia.com.br/connection-pool/5869)







Neste contexto eu tive uma certa dificuldade em
configurar um pool de conexões com JPA. O cenário era um sistema REST que já
estava em produção utilizando Hibernate puro e realizava o pool com C3P0 (já
falaremos dele). Ao colocar as dependências e configurações do JPA o pool para
de funcionar.



Como foi difícil achar a solução, vou compartilhar com
vocês duas configurações de pool, uma direto no servidor Tomcat e outra através
do C3P0. 







Pool de Conexão no Tomcat.







Primeiramente realizamos a
configuração no Tomcat através dos arquivos server.xml e contexto.xml.





Pool de conexão configurado no
arquivo server.xml do Tomcat na tag  através de um
datasource.



 &lt;Resource name="jdbc/TesteDB"   
        auth="Container"   
        type="javax.sql.DataSource"   
        validationInterval="30000"   
        timeBetweenEvictionRunsMillis="30000"   
        maxActive="100"   
        minIdle="10"   
        maxWait="10000"   
        initialSize="10"   
        minEvictableIdleTimeMillis="30000"   
        jmxEnabled="true"   
        jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;  
         org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;  
         org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer"   
        username="dev"   
        password="dev@1"   
        driverClassName="org.postgresql.Driver"   
        url="jdbc:postgresql://192.168.0.165:5432/teste_v_3_1_0"/&gt;  



No arquivo context.xml do Tomcat,
referenciar o datasource criado.

 &lt;ResourceLink name="jdbc/TesteDB"   
        global="jdbc/TesteDB"   
        auth="Container"   
        type="javax.sql.DataSource" /&gt;  



Agora vamos para aplicação e no arquivo
web.xml, referenciamos o datasource através do código abaixo.


 &lt;resource-ref&gt;  
   &lt;description&gt;DB Connection&lt;/description&gt;  
   &lt;res-ref-name&gt;jdbc/TesteDB&lt;/res-ref-name&gt;  
   &lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;  
   &lt;res-auth&gt;Container&lt;/res-auth&gt;  
 &lt;/resource-ref&gt;  




Como a aplicação está utilizando JPA, no arquivo persistence.xml fazemos referência ao datasource com a linha de código abaixo:



 &lt;non-jta-data-source&gt;java:/comp/env/jdbc/TesteDB&lt;/non-jta-data-source&gt;  




Obs: deve ficar logo abaixo da tag.


Ainda no persistence, inclua apenas a propriedade de dialeto.

 &lt;property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" /&gt;  



Agora a parte mais importante, e
a causa de todo o trabalho para configuração, utilizar a versão 5.0.4 ou
superior do hibernate-entitymanger, pois as versões inferiores possui um bug na
utilização de datasource no JPA, o que causou uma certa dor de cabeça. Abaixo
as dependência no arquivo pom do Maven.


 &lt;dependency&gt;  
             &lt;groupId&gt;org.hibernate&lt;/groupId&gt;  
             &lt;artifactId&gt;hibernate-entitymanager&lt;/artifactId&gt;  
             &lt;version&gt;5.0.4.Final&lt;/version&gt;  
         &lt;/dependency&gt;  
          &lt;dependency&gt;  
             &lt;groupId&gt;javax.validation&lt;/groupId&gt;  
             &lt;artifactId&gt;validation-api&lt;/artifactId&gt;  
             &lt;version&gt;1.0.0.GA&lt;/version&gt;  
         &lt;/dependency&gt;  
         &lt;dependency&gt;  
             &lt;groupId&gt;org.hibernate&lt;/groupId&gt;  
             &lt;artifactId&gt;hibernate-validator&lt;/artifactId&gt;  
             &lt;version&gt;5.2.2.Final&lt;/version&gt;  
         &lt;/dependency&gt;  
         &lt;dependency&gt;  
             &lt;groupId&gt;org.hibernate.javax.persistence&lt;/groupId&gt;  
             &lt;artifactId&gt;hibernate-jpa-2.1-api&lt;/artifactId&gt;  
             &lt;version&gt;1.0.0.Final&lt;/version&gt;  
         &lt;/dependency&gt;  



Pool de Conexão com C3P0



c3p0
é uma biblioteca fácil de usar para drivers JDBC tradicionais
"enterprise-ready", meçhorando sua funcionalidade definida pela
especificação JDBC3 e as extensões opcionais para JDBC2.&nbsp;A partir da versão 0.9.5, c3p0 apoia
plenamente a especificação JDBC4.

Em particular, c3p0 fornece vários
serviços úteis:

Uma classe para adaptar os drivers JDBC
     tradicionais baseados em DriverManager para o mais recente regime&nbsp; de
     aquisição de conexões de banco de dados através do javax.sql.DataSource.
Pooling transparente de Conexão e
     PreparedStatements.


A biblioteca se esforça para acertar os
detalhes:

DataSources c3p0 são ambos&nbsp;Referenciável&nbsp;e&nbsp;Serializable,
     e são, portanto, adequados para a ligação de uma ampla variedade de
     serviços de nomenclatura baseado em JNDI.
Declaração e ResultSets são cuidadosamente
     limpos quando Conexões e Demonstrações são alocadas, para evitar a
     exaustão em recursos quando os clientes usam a estratégia de gestão de
     recursos Lazy, mas comum do que apenas limpar suas conexões.&nbsp;
A biblioteca adota a abordagem definida pela
     especificação JDBC 2 e 3. DataSources são escritos no estilo JavaBean, oferecendo
     todo o necessário e a maioria das propriedades opcionais. Todas as interfaces
     internas JDBC-definidos são implementadas (ConnectionPoolDataSource,
     PooledConnection, ConnectionEvent-generating Connections, etc.) Você pode misturar as classes c3p0 com implementações de terceiros
     (embora nem todos os recursos c3p0 irá trabalhar com implementações
     externas de&nbsp;ConnectionPoolDataSource).


c3p0 espera fornecer implementações de
DataSource mais do que adequado para uso por aplicativos corporativos J2EE de
alto volume.



Para configurar o pool com
C3P0 precisamos adicionar suas dependências no pom.xml.

 &lt;dependency&gt;  
             &lt;groupId&gt;com.mchange&lt;/groupId&gt;  
             &lt;artifactId&gt;mchange-commons-java&lt;/artifactId&gt;  
             &lt;version&gt;0.2.10&lt;/version&gt;  
         &lt;/dependency&gt;  
         &lt;dependency&gt;  
             &lt;groupId&gt;c3p0&lt;/groupId&gt;  
             &lt;artifactId&gt;c3p0&lt;/artifactId&gt;  
             &lt;version&gt;0.9.1.2&lt;/version&gt;  
         &lt;/dependency&gt;  



Atualizado a dependência,
basta adicionar as propriedades do C3P0 no arquivo persistence.xml.


 &lt;property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" /&gt;  
             &lt;property name="hibernate.connection.url" value="jdbc:postgresql://192.168.0.165:5432/teste_v_3_1_0" /&gt;  
             &lt;property name="hibernate.connection.username" value="senha" /&gt;  
             &lt;property name="hibernate.connection.driver_class" value="org.postgresql.Driver" /&gt;  
             &lt;property name="hibernate.connection.password" value="password" /&gt;  
       &lt;property name="hibernate.connection.provider"  
              value="org.hibernate.connection.C3P0ConnectionProvider" /&gt;  
          &lt;property name="hibernate.c3p0.min_size" value="5" /&gt;  
           &lt;property name="hibernate.c3p0.max_size" value="100" /&gt;  
           &lt;property name="hibernate.c3p0.timeout" value="300" /&gt;  
           &lt;property name="hibernate.c3p0.max_statements" value="50" /&gt;  
           &lt;property name="hibernate.c3p0.idle_test_period" value="3000" /&gt;  
           &lt;property name="hibernate.c3p0.min_size" value="5" /&gt;  
           &lt;property name="hibernate.c3p0.max_size" value="100" /&gt;  
           &lt;property name="hibernate.c3p0.timeout" value="300" /&gt;  
           &lt;property name="hibernate.c3p0.max_statements" value="50" /&gt;  
           &lt;property name="hibernate.c3p0.idle_test_period" value="3000" /&gt;  



Agora é só tirar o máximo
de proveito do pool de conexão e ser feliz.

O projeto completo está
disponível no GitHub. 



Referências 



http://www.mchange.com/projects/c3p0/

http://www.devmedia.com.br/connection-pool/5869