2

I'm working on Spring Boot Application and I use Spring Data, HikariCP and JDBC, but I have a problem.

Inside one method I get a particular User from the database using a Spring Data repository. After I get the User from the DB I use JdbcTemplate.query to get some other information from the DB with username of above User but the application freezes and after some time it throws

java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30006ms.

When I debug the code I see that jdbctemplate is using hikariCP as datasource.

This is the code I'm using:

 public User getUser() {

     User user = userRepository.findByUsernameAndEnabledTrue("username");

     List<String> roles=  getUserRoles(user.getUsername())

     return user;

 }

 private List<String> getUserRoles(String username) {

     List<String> roles = this.jdbcTemplate.query("SELECT ga.authority FROM group_authorities ga INNER JOIN group_members gm ON gm.group_id = ga.group_id INNER JOIN users u ON gm.username=u.username WHERE u.username=?;",
         new Object[]{username},new ResultSetExtractor<List<String>>() {
             @Override
             public List<String> extractData(ResultSet resultSet) throws SQLException, DataAccessException {
                 List<String> roles = new ArrayList<>();
                 while (resultSet.next()) {
                     roles.add(resultSet.getString("authority"));
                 }
                 return roles;
             }
         });
     return roles;
 }

I made a research how to use those together and share same transaction or something like but unfortunately can't fix it.

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
G.L
  • 139
  • 1
  • 4
  • 16

2 Answers2

2

Your problem seems to be that the JdbcTemplate uses a different connection than your repository. And since the connection pool makes only one connection available and that is already used by the repository, you run into the timeout.

Increasing the capacity of the connection pool would fix that immediate problem, but the repository and the JdbcTemplate would use different connections and therefore transactions, which you probably don't want.

You don't show where your JdbcTemplate gets it's connection from, but that is probably where things go wrong. To fix it get the EntityManager injected. Then get the Connection from it. How to do that is JPA implementation dependent. Here are the versions for Eclipse Link and for Hibernate. Then use that Connection to create your JdbcTemplate.

Community
  • 1
  • 1
Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
0

It is possible just inject DataSource or JdbcTemplate in a custom repository, for example. And if JPA and JDBC calls are inside one transaction (generated by @Transactional, for example), Spring is smart enough to use JPATransactionManager for both cases with the same transaction and connection.

https://billykorando.com/2019/05/06/jpa-or-sql-in-a-spring-boot-application-why-not-both/

v.ladynev
  • 19,275
  • 8
  • 46
  • 67