diff --git a/libraries-data-db/log4j.properties b/libraries-data-db/log4j.properties
index 2173c5d96f..d2a3cae499 100644
--- a/libraries-data-db/log4j.properties
+++ b/libraries-data-db/log4j.properties
@@ -1 +1,4 @@
-log4j.rootLogger=INFO, stdout
+log4j.rootLogger=INFO,stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
+log4j.logger.org.datanucleus=DEBUG
diff --git a/libraries-data-db/pom.xml b/libraries-data-db/pom.xml
index 55fd990a80..66fa24476e 100644
--- a/libraries-data-db/pom.xml
+++ b/libraries-data-db/pom.xml
@@ -115,6 +115,24 @@
mysql
${testcontainers-version}
+
+
+ com.vladmihalcea.flexy-pool
+ flexy-micrometer-metrics
+ ${flexy-pool.version}
+
+
+
+ com.vladmihalcea.flexy-pool
+ flexy-hikaricp
+ ${flexy-pool.version}
+
+
+ com.vladmihalcea.flexy-pool
+ flexy-dropwizard-metrics
+
+
+
org.springframework.boot
@@ -147,6 +165,7 @@
+ org.apache.maven.plugins
maven-antrun-plugin
${maven-antrun-plugin.version}
@@ -284,6 +303,7 @@
5.0.1
13.15.2
2.1.3.Final
+ 2.2.3
1.17.6
diff --git a/libraries-data-db/src/main/java/com/baeldung/libraries/flexypool/FlexypoolConfig.java b/libraries-data-db/src/main/java/com/baeldung/libraries/flexypool/FlexypoolConfig.java
new file mode 100644
index 0000000000..3b6bdca26b
--- /dev/null
+++ b/libraries-data-db/src/main/java/com/baeldung/libraries/flexypool/FlexypoolConfig.java
@@ -0,0 +1,109 @@
+package com.baeldung.libraries.flexypool;
+
+import com.vladmihalcea.flexypool.FlexyPoolDataSource;
+import com.vladmihalcea.flexypool.adaptor.HikariCPPoolAdapter;
+import com.vladmihalcea.flexypool.config.Configuration;
+import com.vladmihalcea.flexypool.connection.ConnectionDecoratorFactoryResolver;
+import com.vladmihalcea.flexypool.event.ConnectionAcquireTimeThresholdExceededEvent;
+import com.vladmihalcea.flexypool.event.ConnectionAcquireTimeoutEvent;
+import com.vladmihalcea.flexypool.event.ConnectionLeaseTimeThresholdExceededEvent;
+import com.vladmihalcea.flexypool.event.EventListener;
+import com.vladmihalcea.flexypool.metric.micrometer.MicrometerMetrics;
+import com.vladmihalcea.flexypool.strategy.IncrementPoolOnTimeoutConnectionAcquiringStrategy;
+import com.vladmihalcea.flexypool.strategy.RetryConnectionAcquiringStrategy;
+import com.vladmihalcea.flexypool.strategy.UniqueNamingStrategy;
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Bean;
+
+import java.util.Arrays;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+@org.springframework.context.annotation.Configuration
+public class FlexypoolConfig {
+
+ @SuppressWarnings("unchecked")
+ @Bean(initMethod = "start", destroyMethod = "stop")
+ public FlexyPoolDataSource flexypoolDataSource() {
+ Configuration configuration = flexypoolConfiguration();
+ return new FlexyPoolDataSource<>(configuration, new IncrementPoolOnTimeoutConnectionAcquiringStrategy.Factory<>(5), new RetryConnectionAcquiringStrategy.Factory<>(2));
+ }
+
+ @Bean
+ public Configuration flexypoolConfiguration() {
+
+ HikariDataSource dataSource = hikariDataSource();
+
+ return new Configuration.Builder<>(UUID.randomUUID().toString(), dataSource, HikariCPPoolAdapter.FACTORY).setMetricsFactory(MicrometerMetrics::new)
+ .setConnectionProxyFactory(ConnectionDecoratorFactoryResolver.INSTANCE.resolve())
+ .setMetricLogReporterMillis(TimeUnit.SECONDS.toMillis(5))
+ .setMetricNamingUniqueName(UniqueNamingStrategy.INSTANCE)
+ .setJmxEnabled(true)
+ .setJmxAutoStart(true)
+ .setConnectionAcquireTimeThresholdMillis(50L)
+ .setConnectionLeaseTimeThresholdMillis(250L)
+ .setEventListenerResolver(() -> Arrays.asList(new ConnectionAcquireTimeoutEventListener(), new ConnectionAcquireTimeThresholdExceededEventListener(), new ConnectionLeaseTimeThresholdExceededEventListener()))
+ .build();
+ }
+
+ @Bean
+ public HikariDataSource hikariDataSource() {
+
+ HikariConfig config = new HikariConfig();
+ config.setJdbcUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;INIT=runscript from 'classpath:/db.sql'");
+ config.setUsername("");
+ config.setPassword("");
+ config.addDataSourceProperty("cachePrepStmts", "true");
+ config.addDataSourceProperty("prepStmtCacheSize", "250");
+ config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
+ config.addDataSourceProperty("minimumPoolSize", "1");
+ config.addDataSourceProperty("maximumPoolSize", "3");
+ config.addDataSourceProperty("connectionTimeout", "1000");
+ return new HikariDataSource(config);
+ }
+}
+
+class ConnectionAcquireTimeThresholdExceededEventListener extends EventListener {
+
+ public static final Logger LOGGER = LoggerFactory.getLogger(ConnectionAcquireTimeThresholdExceededEventListener.class);
+
+ public ConnectionAcquireTimeThresholdExceededEventListener() {
+ super(ConnectionAcquireTimeThresholdExceededEvent.class);
+ }
+
+ @Override
+ public void on(ConnectionAcquireTimeThresholdExceededEvent event) {
+ LOGGER.info("ConnectionAcquireTimeThresholdExceededEvent Caught event {}", event);
+ }
+}
+
+class ConnectionLeaseTimeThresholdExceededEventListener extends EventListener {
+
+ public static final Logger LOGGER = LoggerFactory.getLogger(ConnectionLeaseTimeThresholdExceededEventListener.class);
+
+ public ConnectionLeaseTimeThresholdExceededEventListener() {
+ super(ConnectionLeaseTimeThresholdExceededEvent.class);
+ }
+
+ @Override
+ public void on(ConnectionLeaseTimeThresholdExceededEvent event) {
+ LOGGER.info("ConnectionLeaseTimeThresholdExceededEvent Caught event {}", event);
+ }
+}
+
+class ConnectionAcquireTimeoutEventListener extends EventListener {
+
+ public static final Logger LOGGER = LoggerFactory.getLogger(ConnectionAcquireTimeoutEventListener.class);
+
+ public ConnectionAcquireTimeoutEventListener() {
+ super(ConnectionAcquireTimeoutEvent.class);
+ }
+
+ @Override
+ public void on(ConnectionAcquireTimeoutEvent event) {
+ LOGGER.info("ConnectionAcquireTimeoutEvent Caught event {}", event);
+ }
+}
\ No newline at end of file
diff --git a/libraries-data-db/src/main/java/com/baeldung/libraries/flexypool/FlexypoolDemoApplication.java b/libraries-data-db/src/main/java/com/baeldung/libraries/flexypool/FlexypoolDemoApplication.java
new file mode 100644
index 0000000000..16d342f6f9
--- /dev/null
+++ b/libraries-data-db/src/main/java/com/baeldung/libraries/flexypool/FlexypoolDemoApplication.java
@@ -0,0 +1,53 @@
+package com.baeldung.libraries.flexypool;
+
+import com.baeldung.libraries.hikaricp.Employee;
+import com.vladmihalcea.flexypool.FlexyPoolDataSource;
+import com.zaxxer.hikari.HikariDataSource;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+@SpringBootApplication
+public class FlexypoolDemoApplication {
+
+ private static FlexyPoolDataSource poolDataSource;
+
+ public FlexypoolDemoApplication(FlexyPoolDataSource poolDataSource) {
+ FlexypoolDemoApplication.poolDataSource = poolDataSource;
+ }
+
+ public static List getEmployees() throws SQLException {
+ String SQL_QUERY = "select * from emp";
+ List employees;
+ try (Connection con = poolDataSource.getConnection(); PreparedStatement pst = con.prepareStatement(SQL_QUERY); ResultSet rs = pst.executeQuery();) {
+ employees = new ArrayList<>();
+ Employee employee;
+ while (rs.next()) {
+ employee = new Employee();
+ employee.setEmpNo(rs.getInt("empno"));
+ employee.setEname(rs.getString("ename"));
+ employee.setJob(rs.getString("job"));
+ employee.setMgr(rs.getInt("mgr"));
+ employee.setHiredate(rs.getDate("hiredate"));
+ employee.setSal(rs.getInt("sal"));
+ employee.setComm(rs.getInt("comm"));
+ employee.setDeptno(rs.getInt("deptno"));
+ employees.add(employee);
+ }
+ }
+ return employees;
+ }
+
+ public static void main(String[] args) throws SQLException {
+ SpringApplication.run(FlexypoolDemoApplication.class, args);
+ List employees = getEmployees();
+ System.out.println(employees);
+ }
+
+}