We have a spring boot app running over AKS (Azure Kubernetes Service). In the service, we inject and call a Procedure invoker class:
package com.thing;
import javax.persistence.EntityManager;
import javax.persistence.ParameterMode;
import javax.persistence.PersistenceContext;
import javax.persistence.StoredProcedureQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class ProcedureInvoker {
@PersistenceContext
private final EntityManager entityManager;
@Autowired
public ProcedureInvoker(final EntityManager entityManager) {
this.entityManager = entityManager;
}
public int getValueCall(String user, String password) {
StoredProcedureQuery storedProcedureQuery = entityManager.createStoredProcedureQuery("dbo.CHECK_USER");
// In out parameters
storedProcedureQuery.registerStoredProcedureParameter(1, String.class, ParameterMode.IN);
storedProcedureQuery.registerStoredProcedureParameter(2, String.class, ParameterMode.IN);
storedProcedureQuery.registerStoredProcedureParameter(3, Integer.class, ParameterMode.INOUT);
//
storedProcedureQuery.setParameter(1, user);
storedProcedureQuery.setParameter(2, password);
storedProcedureQuery.setParameter(3, new Integer(-3));
Object result = storedProcedureQuery.getOutputParameterValue(3);
storedProcedureQuery.execute();
int resu = ((Integer)result).intValue();
return resu;
}
}
Sometimes (after 1 day o several hours working properly; about 3000 calls), we start getting this error:
com.microsoft.sqlserver.jdbc.SQLServerException:
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError
(SQLServerException.java227)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.checkClosed
(SQLServerConnection.java796)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.setNetworkTimeout
(SQLServerConnection.java4768)
at com.zaxxer.hikari.pool.PoolBase.setNetworkTimeout (PoolBase.java541)
at com.zaxxer.hikari.pool.PoolBase.quietlyCloseConnection
(PoolBase.java129)
at com.zaxxer.hikari.pool.HikariPool.lambda$closeConnection$1
(HikariPool.java434)
at java.util.concurrent.ThreadPoolExecutor.runWorker
(ThreadPoolExecutor.java1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run
(ThreadPoolExecutor.java624)
at java.lang.Thread.run (Thread.java748)
To solve it, we delete pods in order to restart them. But It is not a solution.
Pom has:
<!-- DDBB -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- End DDBB -->
Properties from yaml
spring.datasource.driverClassName:
com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.jpa.show-sql: false
spring.jpa.hibernate.dialect: org.hibernate.dialect.SQLServer2012Dialect
spring.jpa.properties.hibernate.format_sql: true
logging.level.org.hibernate.type: debug
SOLVED!! Finally we solved it adding a:
entityManager.close()
We thought that sentence is not necessary for procedures or functions (it was closed by spring).
The problem probably comes from SQL Server because the procedure has a return statement which is not declared (We had some problems calling it from Spring). Maybe SQL server delegates the close of the connection to spring and spring made the opposite (delegating to SQL server)