I'm developing a Java-based WebApp which runs on top of JDK-17 and Tomcat 10.0.5 connected to a MySQL 8.0.27 database with mysql-connector-j-8.0.31. There is not problem opening and closing "physical" connections through JDBC. However, when HikariCP is managing connections, I'm falling in errors related with connections availability when I run query updates through CallableStatement and PreparedStatement objects. It is important to mention that I can manage the webapp with no problems using the executeQuery() method from PreparedStatement. The problem occurs with executeUpdate() of PreparedStatement and CallableStatement objects.
This is my JNDI-Resource setup (edited for setting the max pool size and minimum idle with sugested values):
<Resource name="jdbc/MySQLHikari"
auth="Container"
factory="com.zaxxer.hikari.HikariJNDIFactory"
type="javax.sql.DataSource"
minimumIdle="5"
maximumPoolSize="10"
idleTimeout="120000"
connectionTimeout="300000"
leakDetectionThreshold="300000"
dataSourceClassName="com.mysql.cj.jdbc.MysqlDataSource"
dataSource.serverName="127.0.0.1"
dataSource.port="3307"
dataSource.databaseName="optica?useSSL=false&useUnicode=true&characterEncoding=utf-8"
dataSource.user="root"
dataSource.password="root"
dataSource.cachePrepStmts="true"
dataSource.prepStmtCacheSize="250"
dataSource.prepStmtCacheSqlLimit="2048"
dataSource.useServerPrepStmts="true"
dataSource.useLocalSessionState="true"
dataSource.rewriteBatchedStatements="true"
dataSource.cacheResultSetMetadata="true"
dataSource.cacheServerConfiguration="true"
dataSource.elideSetAutoCommits="true"
dataSource.maintainTimeStats="false"
/>
Here is my sample code on how I acquire DB connections from HikariCP:
public class ConexionMySQLProvider
{
private static HikariDataSource hikariDataSource;
private static void buildContext()
{
try
{
Context context = (Context) new InitialContext().lookup("java:/comp/env");
DataSource dataSource = (DataSource) context.lookup("jdbc/MySQLHikari");
HikariConfig config = new HikariConfig();
config.setDataSource(dataSource);
hikariDataSource = new HikariDataSource(config);
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static Connection getFromPool() throws Exception
{
if (hikariDataSource == null)
{
buildContext();
}
return hikariDataSource.getConnection();
}
}
And this is an extract of my persistence controller when the problem occurs:
public class ControllerCliente
{
public int insert(Cliente c) throws Exception
{
String sql = "{call insertarCliente(?, ?, ?, ?, ?, ?, ?, " +
"?, ?, ?, ?, ?, ?, ?, ?, " +
"?, ?, ?)}";
Connection conn = ConexionMySQLProvider.getFromPool();
CallableStatement cstmt = conn.prepareCall(sql);
int idClienteGenerado = -1;
//Next, I fill each required value in the CallableStatement object:
cstmt.setString(1, c.getPersona().getNombre());
...
//Execution of the query:
cstmt.executeUpdate();
//Recovering of generated ID's:
int idClienteGenerado = -1;
...
//A
cstmt.close();
conn.close();
//Devolvemos el ID de Cliente generado:
return idClienteGenerado;
}
public void delete(int id) throws Exception
{
String sql = "UPDATE cliente SET estatus=0 WHERE idCliente=?";
Connection conn = ConexionMySQLProvider.getFromPool();
PreparedStatement pstmt = conn.prepareStatement(sql)
pstmt.setInt(1, id);
pstmt.executeUpdate();
pstmt.close();
conn.close();
}
public List<Cliente> getAll(String filtro) throws Exception
{
String sql = "SELECT * FROM v_clientes WHERE estatus=1";
Connection conn = ConexionMySQLProvider.getFromPool();
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
List<Cliente> clientes = new ArrayList<>();
while (rs.next())
clientes.add(fill(rs));
rs.close();
pstmt.close();
conn.close();
return clientes;
}
private Cliente fill(ResultSet rs) throws Exception
{
Cliente c = new Cliente();
//Fill Cliente from ResultSet
...
return c;
}
}
At the moment of this question:
- I already have read about HikariCP and how to configure it.
- I tried the try-catch with resources approach with the same result.
- I downgraded to mysql-connector 5.1.36 but I was unable to connect with MySQL 8.0.27.
- I tried with the MariaDB JDBC driver with the same result.
- I switched to C3P0 but result is the same: unavailable connections after several executeUpdate() method calls. So, I continue using and exploring HikariCP 5.0.1.
Constraints:
- I must to use MySQL 8.X.
- I need to keep the webapp in top of Java 17 considering a future migration to Java 19.
I hope that you can help me because I was not be able to find information about this issue.