无法加载驱动程序类org.mariadb.jdbc.Driver

时间:2019-11-22 17:58:58

标签: java spring spring-boot spring-data-jpa spring-data

我想在Spring Boot中配置2个JNDI数据源。我尝试了这种配置:

application.properties

spring.production-datasource.jndi-name=java:/global/production_gateway
spring.production-datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update

spring.warehouse-datasource.jndi-name=java:/global/production_warehouse
spring.warehouse-datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update

主要数据源配置:

    @Configuration
@EnableJpaRepositories(
        basePackages = "org.datalis.plugin.production.entity", 
        entityManagerFactoryRef = "productionEntityManager", 
        transactionManagerRef = "productionTransactionManager"
    )
@EnableTransactionManagement
public class ContextProductionDatasource {

    @Autowired
    private Environment env;

    @Primary
    @Bean(name = "productionDataSourceProperties")
    @ConfigurationProperties(prefix="spring.production.datasource")
    public DataSourceProperties productionDataSourceProperties() {
        return new DataSourceProperties();
    }   

    @Primary
    @Bean(name = "productionDataSource")
    @ConfigurationProperties(prefix="spring.production.datasource")
    public DataSource productionDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean(name = "productionEntityManager") 
    public EntityManager productionEntityManager(EntityManagerFactory emf) {
        return emf.createEntityManager();
    }

    @Primary
    @Bean(name = "productionTransactionManager")    
    public PlatformTransactionManager productionTransactionManager(final EntityManagerFactory emf) {
        final JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }

    @Primary
    @Bean(name = "productionExceptionTranslation")
    public PersistenceExceptionTranslationPostProcessor productionExceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }
}

第二个数据源配置:

    @Configuration
@EnableJpaRepositories(
        basePackages = "org.datalis.plugin.warehouse.entity", 
        entityManagerFactoryRef = "warehouseEntityManager", 
        transactionManagerRef = "warehouseTransactionManager"
    )
@EnableTransactionManagement
public class ContextWarehouseDatasource {

    @Autowired
    private Environment env;

    @Bean(name = "warehouseDataSourceProperties")
    @ConfigurationProperties(prefix="spring.warehouse.datasource")
    public DataSourceProperties warehouseDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean(name = "warehouseDataSource")
    @ConfigurationProperties(prefix="spring.warehouse.datasource")
    public DataSource warehouseDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "warehouseEntityManager")  
    public EntityManager warehouseEntityManager(EntityManagerFactory emf) {
        return emf.createEntityManager();
    }

    @Bean(name = "warehouseTransactionManager")
    public PlatformTransactionManager warehouseTransactionManager(final EntityManagerFactory emf) {
        final JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }

    @Bean(name = "warehouseExceptionTranslation")
    public PersistenceExceptionTranslationPostProcessor warehouseExceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }
}

但是在部署过程中出现错误:

    Caused by: java.lang.IllegalStateException: Unable to set value for property driver-class-name
        at deployment.datalis_rest_api.war//org.springframework.boot.context.properties.bind.JavaBeanBinder$BeanProperty.setValue(JavaBeanBinder.java:349)
        at deployment.datalis_rest_api.war//org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:96)
        at deployment.datalis_rest_api.war//org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:79)
        at deployment.datalis_rest_api.war//org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:56)
        at deployment.datalis_rest_api.war//org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$5(Binder.java:452)
        at deployment.datalis_rest_api.war//org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:570)
        at deployment.datalis_rest_api.war//org.springframework.boot.context.properties.bind.Binder$Context.withDataObject(Binder.java:556)
        at deployment.datalis_rest_api.war//org.springframework.boot.context.properties.bind.Binder$Context.access$400(Binder.java:513)
        at deployment.datalis_rest_api.war//org.springframework.boot.context.properties.bind.Binder.bindDataObject(Binder.java:450)
        at deployment.datalis_rest_api.war//org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:391)
        at deployment.datalis_rest_api.war//org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:320)
        ... 132 more
Caused by: java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:567)
        at deployment.datalis_rest_api.war//org.springframework.boot.context.properties.bind.JavaBeanBinder$BeanProperty.setValue(JavaBeanBinder.java:346)
        ... 142 more
Caused by: java.lang.RuntimeException: Failed to load driver class org.mariadb.jdbc.Driver in either of HikariConfig class loader or Thread context classloader
        at deployment.datalis_rest_api.war//com.zaxxer.hikari.HikariConfig.setDriverClassName(HikariConfig.java:485)

我正在使用Spring boot war部署到具有已部署的mariadb-java-client-2.4.2.jar的Wildfly服务器中。当我使用单个数据源配置时,它工作正常。但是有了第二个数据源,我得到了例外。

您知道如何解决此问题吗?

第二次尝试

application.properties:

spring.production.datasource.jndi-name=java:/global/production_gateway
spring.production.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.production.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
spring.production.jpa.show-sql = true
spring.production.jpa.hibernate.ddl-auto = update

spring.warehouse.datasource.jndi-name=java:/global/production_warehouse
spring.warehouse.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.warehouse.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
spring.warehouse.jpa.show-sql = true
spring.warehouse.jpa.hibernate.ddl-auto = update

第一个数据源:

@Configuration
@EnableJpaRepositories(
        basePackages = "org.datalis.plugin.production.entity", 
        entityManagerFactoryRef = "productionEntityManager", 
        transactionManagerRef = "productionTransactionManager"
    )
@EnableTransactionManagement
public class ContextProductionDatasource {

    @Primary
    @Bean(name = "productionDataSourceProperties")
    @ConfigurationProperties(prefix="spring.production")
    public DataSourceProperties productionDataSourceProperties() {
        return new DataSourceProperties();
    }   

    @Primary
    @Bean(name = "productionDataSource")
    @ConfigurationProperties(prefix="spring.production")
    public DataSource productionDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean(name = "productionEntityManager") 
    public EntityManager productionEntityManager(EntityManagerFactory emf) {
        return emf.createEntityManager();
    }

    @Primary
    @Bean(name = "productionTransactionManager")    
    public PlatformTransactionManager productionTransactionManager(final EntityManagerFactory emf) {
        final JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }

    @Primary
    @Bean(name = "productionExceptionTranslation")
    public PersistenceExceptionTranslationPostProcessor productionExceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }
}

第二个数据源:

@Configuration
@EnableJpaRepositories(
        basePackages = "org.datalis.plugin.warehouse.entity", 
        entityManagerFactoryRef = "warehouseEntityManager", 
        transactionManagerRef = "warehouseTransactionManager"
    )
@EnableTransactionManagement
public class ContextWarehouseDatasource {

    @Bean(name = "warehouseDataSourceProperties")
    @ConfigurationProperties(prefix="spring.warehouse")
    public DataSourceProperties warehouseDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean(name = "warehouseDataSource")
    @ConfigurationProperties(prefix="spring.warehouse")
    public DataSource warehouseDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "warehouseEntityManager")  
    public EntityManager warehouseEntityManager(EntityManagerFactory emf) {
        return emf.createEntityManager();
    }

    @Bean(name = "warehouseTransactionManager")
    public PlatformTransactionManager warehouseTransactionManager(final EntityManagerFactory emf) {
        final JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }

    @Bean(name = "warehouseExceptionTranslation")
    public PersistenceExceptionTranslationPostProcessor warehouseExceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }
}

现在我得到了:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'entityManagerFactory' threw exception; nested exception is java.lang.IllegalArgumentException: dataSource or dataSourceClassName or jdbcUrl is required.
        at deployment.datalis_rest_api.war//org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
        at deployment.datalis_rest_api.war//org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:640)
        ... 41 more
Caused by: java.lang.IllegalArgumentException: dataSource or dataSourceClassName or jdbcUrl is required.

2 个答案:

答案 0 :(得分:2)

更正两个entityManager bean的名称:productionEntityManager和WarehouseEntityManager

entityManagerFactoryRef中的

@EnableJpaRepositories是beanName引用

所以使用

@Configuration
@EnableJpaRepositories(
        basePackages = "org.datalis.plugin.production.entity", 
        entityManagerFactoryRef = "productionEntityManager",  
        transactionManagerRef = "productionTransactionManager" 
    )
@EnableTransactionManagement
public class ContextProductionDatasource {

  ...

 @Primary
    @Bean   
    public EntityManager productionEntityManager(EntityManagerFactory emf) {
        return emf.createEntityManager();
    }

@Configuration
@EnableJpaRepositories(
        basePackages = "org.datalis.plugin.warehouse.entity", 
        entityManagerFactoryRef = "warehouseEntityManager", 
        transactionManagerRef = "warehouseTransactionManager"
    )
@EnableTransactionManagement
public class ContextWarehouseDatasource {

   ...

    @Bean   
    public EntityManager warehouseEntityManager(EntityManagerFactory emf) {
        return emf.createEntityManager();
    }

您需要将@ConfigurationProperties中的属性名称与“ -”和“

使用@ConfigurationProperties(prefix="spring.production-datasource")@ConfigurationProperties(prefix="spring.warehouse-datasource")

并确保您的类路径中有驱动程序

喜欢

<dependency>
    <groupId>org.mariadb.jdbc</groupId>
    <artifactId>mariadb-java-client</artifactId>
    <version>2.5.2</version>
    <scope>runtime</scope>
</dependency>

答案 1 :(得分:2)

在属性中,您正在使用spring.production-datasource,但是在春季@Configuration中,您尝试使用@ConfigurationProperties(prefix = "spring.production.datasource")进行映射。从Spring Boot 2开始,宽松的属性绑定规则are now more strict使得此处的破折号和点之间不匹配。

您需要将属性更改为spring.production.datasource或使用@ConfigurationProperties(prefix = "spring.production-datasource")

在配置Spring Boot DataSource时,您可以使用jndi-name或提供连接详细信息,但不能同时提供两者。根据{{​​3}}:

  

spring.datasource.jndi名称

     

JNDI数据源的位置。类别,网址,用户名和密码都会被忽略

您最有可能必须删除spring.production-datasource.driver-class-namejndi-name冲突的属性。