在Spring Boot中使用JTDS配置HikariCP

16
我希望为我的现有Web应用程序添加连接池,该应用程序使用的是Spring Boot 1.5.1。
数据源配置如下,位于application.properties文件中:
spring.datasource.url=jdbc:jtds:sqlserver://localhost:1433;databaseName=MyDatabase;instance=SQLServer2014;
spring.datasource.username=myuser
spring.datasource.password=passwd
spring.datasource.driver-class-name=net.sourceforge.jtds.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update

我不需要进行任何进一步的配置,这已经足够了。

虽然官方文档中显示了参数,但并不清晰,Spring Boot 文档也是如此。

因此,我在那里寻找解决方案(这个, 也是这个...)。

我进行了几次尝试,但每次运行应用程序时,都会抛出关于HikariCP的异常。

当添加spring.datasource.type=com.zaxxer.hikari.HikariDataSource时,将抛出以下异常:

2017-02-15 12:12:23.955  WARN 14844 --- [           main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is java.lang.AbstractMethodError
2017-02-15 12:12:23.964  INFO 14844 --- [           main] utoConfigurationReportLoggingInitializer :
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-02-15 12:12:23.970 ERROR 14844 --- [           main] o.s.boot.SpringApplication               : Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is java.lang.AbstractMethodError
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:856) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
    at com.ingartek.ws.pps.PrestacionesPoliticasSocialesInternoApplication.main(PrestacionesPoliticasSocialesInternoApplication.java:26) [classes/:na]
Caused by: java.lang.AbstractMethodError: null
    at net.sourceforge.jtds.jdbc.JtdsConnection.isValid(JtdsConnection.java:2833) ~[jtds-1.3.1.jar:1.3.1]
    at com.zaxxer.hikari.pool.PoolBase.checkDriverSupport(PoolBase.java:422) ~[HikariCP-2.6.0.jar:na]
    at com.zaxxer.hikari.pool.PoolBase.setupConnection(PoolBase.java:393) ~[HikariCP-2.6.0.jar:na]
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:351) ~[HikariCP-2.6.0.jar:na]
    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:196) ~[HikariCP-2.6.0.jar:na]
    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:442) ~[HikariCP-2.6.0.jar:na]
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:505) ~[HikariCP-2.6.0.jar:na]
    at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:113) ~[HikariCP-2.6.0.jar:na]
    at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:97) ~[HikariCP-2.6.0.jar:na]
    at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) ~[hibernate-core-5.2.6.Final.jar:5.2.6.Final]
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:180) ~[hibernate-core-5.2.6.Final.jar:5.2.6.Final]
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:68) ~[hibernate-core-5.2.6.Final.jar:5.2.6.Final]
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35) ~[hibernate-core-5.2.6.Final.jar:5.2.6.Final]
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:88) ~[hibernate-core-5.2.6.Final.jar:5.2.6.Final]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:257) ~[hibernate-core-5.2.6.Final.jar:5.2.6.Final]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:231) ~[hibernate-core-5.2.6.Final.jar:5.2.6.Final]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:210) ~[hibernate-core-5.2.6.Final.jar:5.2.6.Final]
    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:51) ~[hibernate-core-5.2.6.Final.jar:5.2.6.Final]
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:94) ~[hibernate-core-5.2.6.Final.jar:5.2.6.Final]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:240) ~[hibernate-core-5.2.6.Final.jar:5.2.6.Final]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:210) ~[hibernate-core-5.2.6.Final.jar:5.2.6.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.handleTypes(MetadataBuildingProcess.java:352) ~[hibernate-core-5.2.6.Final.jar:5.2.6.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:111) ~[hibernate-core-5.2.6.Final.jar:5.2.6.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:858) ~[hibernate-core-5.2.6.Final.jar:5.2.6.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:885) ~[hibernate-core-5.2.6.Final.jar:5.2.6.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) ~[spring-orm-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353) ~[spring-orm-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:373) ~[spring-orm-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:362) ~[spring-orm-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    ... 16 common frames omitted

那么,将hikaricp添加到我的application.properties文件中的最简单方法是什么?


你能展示一下你的pom.xml文件吗? - abaghel
@abaghel 这个相关吗? - joninx
3个回答

37

您遇到了以下错误。

Caused by: java.lang.AbstractMethodError: null at net.sourceforge.jtds.jdbc.JtdsConnection.isValid(JtdsConnection.java:2833)

问题在于net.sourceforge.jtds.jdbc.JtdsConnection没有实现isValid,因此您需要指定一个连接测试查询以确保不会调用isValid方法。尝试在您的application.properties文件中添加下面的属性:

spring.datasource.hikari.connection-test-query=SELECT 1

1
我在使用Spring Boot 2.1.5时遇到了这个问题,使用这个方法解决了! - davidwaf
太棒了!它可以在Spring Boot 2.5.x中运行。 - Efriandika Pratama
我感激你,现在我感觉很平静。 - mj. rahmati

17

为了使用多个数据源(Spring Boot 2.0),我必须按照以下步骤才能使其正常工作(只有在使用单个数据源时,设置spring.datasource.hikari.connection-test-query属性才有效):

@Configuration
public class DataConfig {
    @Bean
    @Primary
    @ConfigurationProperties(prefix="spring.datasource")
    public DataSource primaryDataSource() {
        HikariDataSource ds = (HikariDataSource) DataSourceBuilder.create().build();

        ds.setConnectionTestQuery("SELECT 1");

        return ds;
    }

    @Bean(name="secondDataSource")
    @ConfigurationProperties(prefix="spring.datasource.second")
    public DataSource secondDataSource() {
        HikariDataSource ds = (HikariDataSource) DataSourceBuilder.create().build();

        ds.setConnectionTestQuery("SELECT 1");

        return ds;
    }

    @Bean(name="primaryJdbcTemplate")
    public JdbcTemplate primaryJdbcTemplate(DataSource primaryDataSource) {
        return new JdbcTemplate(primaryDataSource);
    }

    @Bean(name="secondJdbcTemplate")
    public JdbcTemplate secondJdbcTemplate(@Qualifier("secondDataSource") DataSource secondDataSource) {
        return new JdbcTemplate(secondDataSource);
    }
}

即使这应该适用于多个数据源,在我的应用程序中,这解决了单个数据源的问题(属性 spring.datasource.hikari.connection-test-query 未起作用)。 - Alessandro C

0

我遇到了同样的问题,并从这个讨论中找到了解决方案。 看起来,在进行任何进一步的配置之前,Hikari CP通过执行一个测试查询来测试连接的有效性,而在这种情况下缺少了一个测试查询。 因此,如早期答案所建议的那样,您应该在application.properties文件中添加一个测试查询。 如果您正在使用Oracle或mySql,则可以改用以下查询(因为SELECT 1在此处不起作用):

spring.datasource.hikari.connection-test-query=SELECT 1 FROM DUAL

注意:DUAL是Oracle和其他数据库中存在的特殊单行单列表。因此,它可以轻松地用于执行简单的测试查询。


2
Oracle和MySQL不需要测试查询,因为两个驱动程序都实现了isValid()方法。 - brettw
如果是这样,那么为什么我在使用ojdbc7 10.x时也遇到了同样的问题呢?这是否取决于ojdbc jar的版本? - Sen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接