Spring 数据 JPA 和 JDBC 模板
Spring Data JPA and JDBC template
我正在开发 Spring 引导应用程序,我使用 Spring 数据、HikariCP 和 JDBC,但我遇到了问题。
在一种方法中,我使用 Spring 数据存储库从数据库中获取特定的 User
。在我从数据库中获取 User
之后,我使用 JdbcTemplate.query
从数据库中获取一些其他信息 username
以上 User
但应用程序冻结并在一段时间后抛出
java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30006ms.
当我调试代码时,我看到 jdbctemplate
正在使用 hikariCP 作为 datasource
。
这是我正在使用的代码:
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;
}
我研究了如何一起使用它们并共享相同的交易或类似的东西,但遗憾的是无法修复它。
您的问题似乎是 JdbcTemplate
使用与您的存储库不同的连接。由于连接池只提供一个连接,并且存储库已使用该连接,因此您 运行 超时。
增加连接池的容量可以解决这个紧迫的问题,但是存储库和 JdbcTemplate
会使用不同的连接和事务,您可能不希望这样。
您没有显示您的 JdbcTemplate
从哪里获得连接,但这可能是问题所在。要修复它,请注入 EntityManager
。然后从中获取 Connection
。如何做到这一点取决于 JPA 实现。这是版本 for Eclipse Link and for Hibernate。然后使用 Connection
创建您的 JdbcTemplate
.
例如,可以在自定义存储库中注入 DataSource
或 JdbcTemplate
。如果 JPA 和 JDBC 调用在一个事务内(例如,由 @Transactional
生成),Spring 足够聪明,可以对具有相同事务的两种情况使用 JPATransactionManager
和连接。
https://billykorando.com/2019/05/06/jpa-or-sql-in-a-spring-boot-application-why-not-both/
我正在开发 Spring 引导应用程序,我使用 Spring 数据、HikariCP 和 JDBC,但我遇到了问题。
在一种方法中,我使用 Spring 数据存储库从数据库中获取特定的 User
。在我从数据库中获取 User
之后,我使用 JdbcTemplate.query
从数据库中获取一些其他信息 username
以上 User
但应用程序冻结并在一段时间后抛出
java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30006ms.
当我调试代码时,我看到 jdbctemplate
正在使用 hikariCP 作为 datasource
。
这是我正在使用的代码:
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;
}
我研究了如何一起使用它们并共享相同的交易或类似的东西,但遗憾的是无法修复它。
您的问题似乎是 JdbcTemplate
使用与您的存储库不同的连接。由于连接池只提供一个连接,并且存储库已使用该连接,因此您 运行 超时。
增加连接池的容量可以解决这个紧迫的问题,但是存储库和 JdbcTemplate
会使用不同的连接和事务,您可能不希望这样。
您没有显示您的 JdbcTemplate
从哪里获得连接,但这可能是问题所在。要修复它,请注入 EntityManager
。然后从中获取 Connection
。如何做到这一点取决于 JPA 实现。这是版本 for Eclipse Link and for Hibernate。然后使用 Connection
创建您的 JdbcTemplate
.
例如,可以在自定义存储库中注入 DataSource
或 JdbcTemplate
。如果 JPA 和 JDBC 调用在一个事务内(例如,由 @Transactional
生成),Spring 足够聪明,可以对具有相同事务的两种情况使用 JPATransactionManager
和连接。
https://billykorando.com/2019/05/06/jpa-or-sql-in-a-spring-boot-application-why-not-both/