I am using Spring 2.7.2 and I keep getting this WARN log when I do an operation that involves the database after some minutes passes by:
HikariPool-1 - Failed to validate connection com.mysql.cj.jdbc.ConnectionImpl@ (No operations allowed after connection closed.). Possibly consider using a shorter maxLifetime value.
So I did use shorter and shorter value in this property max-lifetime: 140000
but I keep getting the warning, and checking in the database with query show global variables like '%wait_timeout%';
I have the following values:
wait_timeout I understand is the one that matters there, and it is in seconds, so that would be 10 minutes, and my current configuration is 140000 milliseconds which is 2 minutes and 20 seconds, so I should not be getting this WARN log. So the thing is it is my first time using a Datasource Bean, so right now I guessing that the problem is it is still being configured with the default value for max-lifetime
because at the hikari documentation https://github.com/brettwooldridge/HikariCP it says that the default value is 1800000 (30 minutes) which is way above the wait_timeout
value at mysql datbase im connecting (10 minutes), so thats why I think the Datasource bean is not getting the config I am specifing in properties, so here is the Bean:
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DataSourceConfig {
@Bean
@Qualifier("datasource")
public DataSource getDataSource(final @Value("${spring.datasource.host}") String host,
final @Value("${spring.datasource.username}") String user,
final @Value("${spring.datasource.password}") String password)
throws DecrypterException {
return DataSourceBuilder.create().url(String.format(
"jdbc:mysql://%s/%s?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&useSSL=false",
decrypter.getEnv(host), "databasename")).username(user).password(decrypter.getEnv(password)).build();
}
}
I must do it like that cause the host and the password are encrypted environment variables that can only be decrypted with a specific library, so I also have other properties, here is the properties yml:
spring:
datasource:
host: ENCRYPTED_HOST
username: normal_user
password: ENCRYPTED_PASSWORD
driverClassName: com.mysql.cj.jdbc.Driver
hikari:
maximum-pool-size: 65
max-lifetime: 140000
jpa:
open-in-view: false
show-sql: false
Am I missing something?? Is the Bean not being able to get the configurations specified in the application yml? Maybe the time specified in the max-lifetime property for some reason is seconds instead of milliseconds? (going to try this but I doubt it)...
Or maybe I need to do something like this (?) there in the Bean definition since it wont get it from the properties:
HikariConfig config = new HikariConfig();
config.setMaxLifetime(140000);
config.setMaximumPoolSize(65);
HikariDataSource source = new HikariDataSource(config);
DataSourceBuilder builder = DataSourceBuilder.create();
builder.derivedFrom(source);
If so where can I see a good example? Would like to keep all the default configs (except the maxPoolSize and maxLifeTime im trying to configure ofcourse) like it would normally be if all was configured via application.yml and no datasource beans, or it happens by default this way too? Thanks in advance