使用JPA升级Spring Boot 2无法实例化[com.zaxxer.hikari.HikariDataSource]

时间:2018-06-13 02:16:08

标签: java spring spring-boot hikaricp

我升级到Spring Boot 2.0.1.RELEASE,使用Spring数据JPA和Eclipselink作为我的提供者和Liquibase。我尝试启动服务器时遇到以下错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquibase' defined in class path resource [com/zoomdata/scheduler/service/dao/JPASpringConfiguration.class]: Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Illegal arguments to factory method 'dataSource'; args: ; nested exception is java.lang.IllegalArgumentException: wrong number of arguments
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1702)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:579)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:501)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:304)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1089)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:859)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:327)
    at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:137)
    at com.zoomdata.scheduler.service.Main.main(Main.java:54)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Illegal arguments to factory method 'dataSource'; args: ; nested exception is java.lang.IllegalArgumentException: wrong number of arguments
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:587)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1250)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1099)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:541)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:501)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$1(AbstractBeanFactory.java:353)
    at org.springframework.cloud.context.scope.GenericScope$BeanLifecycleWrapper.getBean(GenericScope.java:385)
    at org.springframework.cloud.context.scope.GenericScope.get(GenericScope.java:184)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:350)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
    at com.zaxxer.hikari.HikariDataSource$$EnhancerBySpringCGLIB$$fea845fa.getConnection(<generated>)
    at com.zoomdata.scheduler.service.dao.JPASpringConfiguration$1.afterPropertiesSet(JPASpringConfiguration.java:85)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1761)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1698)
    ... 17 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Illegal arguments to factory method 'dataSource'; args: ; nested exception is java.lang.IllegalArgumentException: wrong number of arguments
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:172)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:579)
    ... 32 common frames omitted
Caused by: java.lang.IllegalArgumentException: wrong number of arguments
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
    ... 33 common frames omitted

我的POM中的依赖项是:

<dependencyManagement>
        <dependencies>
            <dependency>
                <!-- Import dependency management from Spring Boot -->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.0.1.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-commons</artifactId>
            <version>2.0.0.RC1</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-actuator-autoconfigure</artifactId>
            <version>2.0.1.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.0.10.Final</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.3.1.Final</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
            <version>2.0.1.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-commons</artifactId>
            <version>2.0.7.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.persistence</groupId>
            <artifactId>eclipselink</artifactId>
            <version>2.7.1</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>2.0.1.RELEASE</version>
            <exclusions>
                <exclusion>
                    <artifactId>hibernate-core</artifactId>
                    <groupId>org.hibernate</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>hibernate-entitymanager</artifactId>
                    <groupId>org.hibernate</groupId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework.data</groupId>
                    <artifactId>spring-data-jpa</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>log4j-over-slf4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>2.0.7.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-orm</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>42.2.2</version>
    </dependency>
</dependencies>

我的JPA配置类如下所示:

@Configuration
@EnableJpaRepositories("com.example.my.classes")
@EntityScan({"com.example.entities"})
public class JPASpringConfiguration extends JpaBaseConfiguration {

    private String targetDatabase;
    private final String sqlLoggingLevel;

    @Autowired
    public JPASpringConfiguration(
        @Value("${spring.datasource.target-database}") String targetDatabase,
        @Value("${eclipselink.logging.level.sql:INFO}") String sqlLoggingLevel,
        DataSource dataSource,
        JpaProperties jpaProperties,
        ObjectProvider<JtaTransactionManager> transactionManagerObjectProvider,
        ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
        super(dataSource, jpaProperties, transactionManagerObjectProvider, transactionManagerCustomizers);
        this.targetDatabase = targetDatabase;
        this.sqlLoggingLevel = sqlLoggingLevel;
    }

    @Override
    protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
        return new EclipseLinkJpaVendorAdapter();
    }

    @Override
    protected Map<String, Object> getVendorProperties() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("eclipselink.weaving", "false");
        map.put("eclipselink.target-database", targetDatabase);
        map.put("eclipselink.logging.level.sql", sqlLoggingLevel);
        map.put("eclipselink.cache.shared.default", "false");
        map.put(PersistenceUnitProperties.SESSION_CUSTOMIZER, IDSequenceRegistrar.class.getName());
        return map;
    }

    @Bean
    public SpringLiquibase liquibase(DataSource dataSource) {
        SpringLiquibase springLiquibase = new SpringLiquibase() {

            @Override
            public void afterPropertiesSet() throws LiquibaseException {
                configureLiquibase();
                Liquibase liquibase = null;
                try (Connection versionConnection = dataSource.getConnection()) {
                    versionConnection.setAutoCommit(true);
                    liquibase = createLiquibase(dataSource.getConnection());

                    String version = getDbVersion(versionConnection);
                    String previous = null;
                    while (!Objects.equals(version, previous)) {
                        setContexts(version);
                        performUpdate(liquibase);
                        previous = version;
                        version = getDbVersion(versionConnection);
                    }
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                } finally {
                    if (liquibase != null && liquibase.getDatabase() != null) {
                        liquibase.getDatabase().close();
                    }
                }
            }
        };
        springLiquibase.setDataSource(dataSource);
        springLiquibase.setChangeLog("classpath:/upgrade/db-changelog.xml");
        return springLiquibase;
    }

    private String getDbVersion(Connection connection) throws SQLException {
        String sql = "select tag from databasechangelog where tag is not null order by dateexecuted desc";
        try (Statement statement = connection.createStatement();
             ResultSet rs = statement.executeQuery(sql)) {
            if (rs.next()) {
                return rs.getString(1);
            }
            return "initial";
        } catch (SQLException e) {
            try (ResultSet rs = connection.getMetaData().getTables(null, null, "databasechangelog", null)) {
                if (rs.next()) {
                    throw e;
                } else {
                    return "initial";
                }
            }
        }
    }

    private void configureLiquibase() {
        ChangeFactory.getInstance().register(ChangeSetAwareCustomChangeWrapper.class);
    }
}

在我的application.properties中,我定义了:

spring.datasource.target-database=PostgreSQL
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/mydatabase
spring.datasource.username=myuser
spring.datasource.password=mypassword

spring.datasource.max-active=20
spring.datasource.max-idle=4
spring.datasource.max-wait=60000
spring.datasource.min-idle=2
spring.datasource.test-on-borrow=true
spring.datasource.test-on-return=true
spring.datasource.time-between-eviction-runs-millis=120000
spring.datasource.validation-query=select 1

这在以前的Spring Boot 1.3.5中工作(在Spring Boot 2中的HikariCP开关之前)。 JPASpringConfiguration以前能够在没有附加参数的情况下调用super()。

当我在SimpleInstantiationStrategy中放置断点时,我可以看到传递的args为null。

到目前为止,我已尝试过:

  • 使用spring.datasource.hikari。* properties
  • 将@AutoConfigureAfter({DataSourceAutoConfiguration.class})添加到我的 配置类
  • 从当前由Spring Boot提供的内容将HikariCP升级到3.2.0
  • 各种配置选项,属性和类的其他几种返工

感谢任何可以提供帮助的人!

1 个答案:

答案 0 :(得分:1)

我可以将 springboot hikari 一起使用。我没看到下课。你可以添加和检查吗?

@Configuration
@ConfigurationProperties(prefix = "spring.datasource.hikari")
public class CustomHikariConfig extends HikariConfig {

    @Bean
    public DataSource dataSource() {
        return new HikariDataSource(this);
    }

}

虽然您已经提到过使用了 spring.datasource.hikari。* ,但您可以再次使用下面提到的属性重新检查(如果您错过了任何一个)

###
# HikariCP Properties
###

spring.datasource.hikari.connection-timeout=60000
spring.datasource.hikari.maximum-pool-size=200
spring.datasource.hikari.minimum-idle=30
spring.datasource.hikari.idle-timeout=3000
spring.datasource.hikari.poolName=HikariCP
spring.datasource.type=com.zaxxer.hikari.HikariDataSource



spring.datasource.hikari.jdbcUrl=**data source url**
spring.datasource.hikari.username=**username**
spring.datasource.hikari.password=**password**
spring.datasource.hikari.driverClassName=com.mysql.jdbc.Driver