MariaDB-Access 失败:错误 com.zaxxer.hikari.HikariConfig - HikariPool-1 - dataSource or dataSourceClassNa

Posted

技术标签:

【中文标题】MariaDB-Access 失败:错误 com.zaxxer.hikari.HikariConfig - HikariPool-1 - dataSource or dataSourceClassName or jdbcUrl is required【英文标题】:Fail MariaDB-Access: ERROR com.zaxxer.hikari.HikariConfig - HikariPool-1 - dataSource or dataSourceClassName or jdbcUrl is required 【发布时间】:2022-01-07 22:12:31 【问题描述】:

在开始一个新项目时,我被阻止了,因为我无法通过 Spring 和 myBatis 访问数据库。我不明白为什么。

我已经设置了我的 application.properties(通过从我的另一个 项目)。 我已经通过 java-class 设置了 MyBatis-@Configuration (DefaultDataAccessConfig.java) 我已经通过 xml 文件设置了我的 Spring 上下文(也几乎与 之前)。 我的 MainClass 设置也和以前一样。

通过 MainClass 访问时出现错误。

当通过我的 JUnit5-Test 访问时我很好。

所有 spring 设置工作正常,类被实例化并且可以访问。但是在存储数据时,程序失败了,因为缺少 dataSource 缺少 dataSourceClassName 缺少 jdbcUrl(我调试了它,也不存在)。我的测试调用了通过 MainClass 调用时失败的相同方法。 我不知道为什么 myBatis 在 MainClass 启动期间没有正确设置。

我盯着配置看,不知道出了什么问题。 看起来是这样的:

application.properties

server.port = 8192
logging.level.root=WARN

management.endpoints.web.exposure.include=*
management.endpoint.shutdown.enabled=true
endpoints.shutdown.enabled=true

spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.jdbcUrl=jdbc:mysql://DESKTOP-IOL7CPB.fritz.box:3306/smarthome?useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.username=*******
spring.datasource.password=*******
spring.datasource.maximum-pool-size=30
# Number of ms to wait before throwing an exception if no connection is available.
spring.datasource.tomcat.max-wait=60000
# Maximum number of active connections that can be allocated from this pool at the same time.
spring.datasource.tomcat.max-active=50
# Validate the connection before borrowing it from the pool.
spring.datasource.tomcat.test-on-borrow=true 

DefaultDataAccessConfig.java

package de.gombers.smarthome.fritzbox.mybatis.configuration;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.TypeHandler;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import com.zaxxer.hikari.HikariDataSource;

@Configuration
@MapperScan(
    "de.gombers.smarthome.fritzbox.mybatis")  
public class DefaultDataAccessConfig 

    @Bean
    public SqlSessionFactory sqlSessionFactory(@Autowired @Qualifier("myDataSource") DataSource dataSource) throws Exception 
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sessionFactory.setDataSource(dataSource);
        Resource[] resources = resolver.getResources("classpath*:mybatis/*-mapper.xml");
        sessionFactory.setMapperLocations(resources);
        @SuppressWarnings("rawtypes")
        TypeHandler[] typeHandlers =  new CustomDateTypeHandler() ;
        sessionFactory.setTypeHandlers(typeHandlers);
        return sessionFactory.getObject();
    
    
    @Bean
    @ConfigurationProperties("spring.datasource")
    public HikariDataSource myDataSource() 
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    
    
    
    @Bean 
    public SqlSession sqlSession(@Autowired SqlSessionFactory sqlSessionFactory) 
        return sqlSessionFactory.openSession();
        
    

/context/smartHome.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <!-- enable autowire -->
    <context:component-scan
        base-package="de.gombers.smarthome" />
</beans>

主类

@Service
public class GatherStatisticsMain 
    private static final Logger LOGGER = LoggerFactory.getLogger(GatherStatisticsMain.class);

    private final static String contextxml="/context/smartHome.xml";
    
    @Autowired
    private HomeAutomation homeAutomation;
    
    @Autowired
    private StoreDevices storeDevices;

    public GatherStatisticsMain() 
    

    public void process() throws InterruptedException 
        final DeviceList devices = homeAutomation.getDeviceListInfos();
        storeDevices.process(devices);
    

    public static void main(String[] args) throws InterruptedException 
        ApplicationContext context = new ClassPathXmlApplicationContext(contextxml);
        LOGGER.info("------------" + context.getBeanDefinitionCount());

        GatherStatisticsMain main = (GatherStatisticsMain) context.getBean(GatherStatisticsMain.class);
        main.process();
    

JUnit5-测试

@SpringBootTest
@ExtendWith(SpringExtension.class)
@ContextConfiguration("classpath:context/smartHome.xml")
@EnableAutoConfiguration
public class DevicesDAOTest 
    private static final Logger LOGGER = LoggerFactory.getLogger(Tools.getSimpleClassName());
    @Autowired
    private DevicesDAO devicesDAO;
    @Autowired
    private DeviceBuilder devicesBuilder;
    
    
    @Test
    @DisplayName("Add new device")
    public void addDeviceTest() throws DatatypeConfigurationException 
        DeviceType device = devicesBuilder
                .init()
                .setIdentifier("Identifier")
                .setManufacturer("Manufact")
                .setName("Name")
                .setProductname("ProductName")
                .build();
        try 
            Optional<DeviceType> oDevice = devicesDAO.getDeviceByIdentifier(device.getIdentifier());
            devicesDAO.deleteDeviceByIdentifier(device.getIdentifier());
         catch (Exception e) 
            LOGGER.info("No previous occurence of device '' to be deleted", device.getIdentifier());
        
        devicesDAO.insertDevice(device);
        Long count = devicesDAO.getTotalRows();
        Long result = 1L;
        assertEquals("Size ok", result, count);
    

我看到的错误是:

10:06:57.159 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Creating a new SqlSession
10:06:57.159 [main] DEBUG org.mybatis.spring.SqlSessionUtils - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7bebcd65] was not registered for synchronization because synchronization is not active
10:06:57.163 [main] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource
10:06:57.164 [main] ERROR com.zaxxer.hikari.HikariConfig - HikariPool-1 - dataSource or dataSourceClassName or jdbcUrl is required.
10:06:57.164 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7bebcd65]
Exception in thread "main" org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.lang.IllegalArgumentException: dataSource or dataSourceClassName or jdbcUrl is required.
### The error may exist in file [E:\$SysProg\GIT\SmallTools\SmartHome\target\classes\mybatis\Devices-mapper.xml]
### The error may involve de.gombers.smarthome.fritzbox.mybatis.objects.DevicesMapper.getDeviceByIdentifier
### The error occurred while executing a query
### Cause: java.lang.IllegalArgumentException: dataSource or dataSourceClassName or jdbcUrl is required.
    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:79)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:447)
    at com.sun.proxy.$Proxy21.selectOne(Unknown Source)
    at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:167)
    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:82)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:59)
    at com.sun.proxy.$Proxy22.getDeviceByIdentifier(Unknown Source)
    at de.gombers.smarthome.fritzbox.mybatis.objects.DevicesDAO.getDeviceByIdentifier(DevicesDAO.java:35)
    at de.gombers.smarthome.fritzbox.mybatis.serializer.StoreDevices.isAlreadyPersisted(StoreDevices.java:56)
    at de.gombers.smarthome.fritzbox.mybatis.serializer.StoreDevices.storeDevice(StoreDevices.java:44)
    at de.gombers.smarthome.fritzbox.mybatis.serializer.StoreDevices.process(StoreDevices.java:39)
    at de.gombers.smarthome.fritzbox.main.GatherStatisticsMain.process(GatherStatisticsMain.java:62)
    at de.gombers.smarthome.fritzbox.main.GatherStatisticsMain.main(GatherStatisticsMain.java:78)

【问题讨论】:

您正在使用 Spring Boot 但不是...放弃您的数据源 bean 定义,将您的 new ClassPathXmlApplicationContext 更改为 SpringBootApplication.run(GatherStatisticsMain, args); 并重新启动。 【参考方案1】:

您正在使用 Spring Boot,但也非常努力不这样做。

    放弃您的 xml 配置 抛弃你的DataSource bean 在GatherStatisticsMain 上使用@SpringBootApplication 而不是@Service 修复您的main 以使用SpringApplication.run 而不是new ApplicationContext
@Configuration
@MapperScan(
    "de.gombers.smarthome.fritzbox.mybatis")  
public class DefaultDataAccessConfig 

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception 
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sessionFactory.setDataSource(dataSource);
        Resource[] resources = resolver.getResources("classpath*:mybatis/*-mapper.xml");
        sessionFactory.setMapperLocations(resources);
        @SuppressWarnings("rawtypes")
        TypeHandler[] typeHandlers =  new CustomDateTypeHandler() ;
        sessionFactory.setTypeHandlers(typeHandlers);
        return sessionFactory.getObject();
    
 
    @Bean 
    public SqlSession sqlSession(SqlSessionFactory sqlSessionFactory) 
        return sqlSessionFactory.openSession();
        
    

注意:当使用 MyBatis Spring Boot 启动器时,我认为你甚至可以放弃这个配置类。

@SpringBootApplication
public class GatherStatisticsMain 
    private static final Logger LOGGER = LoggerFactory.getLogger(GatherStatisticsMain.class);

    private final static String contextxml="/context/smartHome.xml";
    
    @Autowired
    private HomeAutomation homeAutomation;
    
    @Autowired
    private StoreDevices storeDevices;

    public void process() throws InterruptedException 
        final DeviceList devices = homeAutomation.getDeviceListInfos();
        storeDevices.process(devices);
    

    public static void main(String[] args) throws InterruptedException 
        ApplicationContext context = SpringBootApplication.run(GatherStatisticsMain.class, args);         LOGGER.info("------------" + context.getBeanDefinitionCount());

        GatherStatisticsMain main context.getBean(GatherStatisticsMain.class);
        main.process();
    

您的测试类现在应该如下所示。

@SpringBootTest
public class DevicesDAOTest  ... 

【讨论】:

对不起,我不明白这是如何工作的:(1)如果我删除 xml,spring 将不会扫描包中的 beans。我可以通过注释来介绍这一点,但有什么区别。 (2) 删除数据源无济于事。我目前失败了,因为我没有。单元测试甚至可以很好地使用这个定义。你的建议失败了。 Main 也不起作用。 (3) 用\@ SpringBootApplication 代替\@Service 运行没有区别。 (4) 单元测试看起来已经如您所建议的那样。但它也需要数据源,如上所述。 阅读了一些关于 mybatis-spring-boot 的内容,并了解到,至少,这可以帮助自动完成大量关于后台设置的工作。所以你可能是对的,虽然我还不明白。似乎要让人们知道这一点将变得很困难。至少,到目前为止,谢谢你。 1. Spring Boot 默认情况下会这样做。 2. 是的,例如,如果您指定正确的属性spring.datasource.url,它将如此。 3. 比你说的还没有做。 4. 不,您没有加载更多注释。【参考方案2】:

感谢 M. Deinum,他让我走上了正轨。我不知道 mybatis-spring-boot-starter。正如我所说,我 尝试使用 @SpringBootApplication 启动主类 - 并且失败并出现同样的错误。现在我了解到,它失败了,因为“DefaultDataAccessConfig.class”。现在我也可以在失败之间切换,只需引入这个类。此类实例化的 bean 似乎以某种方式干扰了正确的设置。

这是一种魔法。我删除了

/context/smartHome.xml DefaultDataAccessConfig.java

并按照建议运行 MainClass。

【讨论】:

以上是关于MariaDB-Access 失败:错误 com.zaxxer.hikari.HikariConfig - HikariPool-1 - dataSource or dataSourceClassNa的主要内容,如果未能解决你的问题,请参考以下文章

由于以下错误,检索具有 CLSID XXXX 的组件的 COM 类工厂失败:80080005

由于以下错误,检索具有 CLSID XXXX 的组件的 COM 类工厂失败:80040154

错误:任务“:app:dexDebug”执行失败。 com.android.ide.common.process.ProcessException

Gradle构建失败,错误无法解析:com.android.support

错误域=com.alamofire.error.serialization.response Code=-1011 “请求失败:内部服务器错误(500)”

检索 COM 类工厂中 CLSID 为 的组件时失败,原因是出现以下错误: 80040154。