You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

多版本MySQL驱动依赖配置与HikariCP+Hibernate使用问题排查

解决连接MySQL 5和8双版本数据库的HikariCP+Maven配置问题

首先,我们来拆解你遇到的几个核心问题,然后一步步解决:

1. Maven依赖的错误与冲突

你pom.xml里的第二个依赖犯了一个低级错误:groupId写成了mysql.(多了个句号),这会导致Maven无法正确识别这个依赖。即使修正了这个问题,同时引入两个版本的MySQL驱动也会引发类加载冲突——Maven的依赖调解机制会自动选择一个版本(通常是更新的8.0.21),另一个版本的类可能无法被正确加载。

最优解决方案:用MySQL 8驱动向下兼容

MySQL 8.0的官方驱动(mysql-connector-java 8.x版本)是向下兼容MySQL 5.6及以上版本的,所以你完全可以只保留8.0.21的驱动,同时连接MySQL 5和8,这样彻底避免依赖冲突:

<!-- 只保留这一个依赖即可 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.21</version>
</dependency>

如果你因为特殊原因必须使用对应版本的驱动,那需要通过类加载器隔离(比如Java模块、自定义类加载器)来分隔两个版本的驱动类,这会复杂很多,不推荐。

2. 驱动类与数据库配置的对应问题

你遇到的hibernate.connection.driver_class错误,核心是驱动类的选择和数据库版本不匹配:

  • MySQL 5:传统驱动类是com.mysql.jdbc.Driver,但在8.x驱动中这个类只是兼容类,实际会代理到com.mysql.cj.jdbc.Driver
  • MySQL 8:必须使用新的驱动类com.mysql.cj.jdbc.Driver,而且URL必须指定时区参数(比如serverTimezone=UTC

同时,Hibernate方言也要对应:

  • MySQL 5用org.hibernate.dialect.MySQL5Dialect
  • MySQL 8用org.hibernate.dialect.MySQL8Dialect

3. 为双数据库配置独立的SessionFactory

你当前的代码只能构建一个SessionFactory,但你需要连接两个不同的数据库,所以必须为每个数据库单独创建SessionFactory实例,每个实例对应自己的配置:

重构你的SessionFactory构建代码

// 新增参数DbModel,每个DbModel对应一个数据库的配置
protected SessionFactory buildSessionFactory(DbModel dbModel, List<Class> entityClasses) {
    StandardServiceRegistry registry = null;
    StandardServiceRegistryBuilder registryBuilder = new StandardServiceRegistryBuilder();
    try {
        registry = registryBuilder.applySettings(buildDbSettings(dbModel)).build();
        MetadataSources metadataSources = new MetadataSources(registry);
        for (Class<?> entity : entityClasses) {
            metadataSources.addAnnotatedClass(entity);
        }
        Metadata metadata = metadataSources.getMetadataBuilder().build();
        return metadata.getSessionFactoryBuilder().build();
    } catch (Exception e) {
        if (registry != null) StandardServiceRegistryBuilder.destroy(registry);
        System.err.println("SessionFactory创建失败:" + e.getMessage());
        throw new ExceptionInInitializerError(e);
    }
}

private Map<String, Object> buildDbSettings(DbModel dbModel) {
    Map<String, Object> settings = new HashMap<>();
    // 驱动类根据数据库版本传入正确值
    settings.put(Environment.DRIVER, dbModel.getDriver());
    // 方言也要对应版本
    settings.put(Environment.DIALECT, dbModel.getDialect());
    settings.put(Environment.URL, dbModel.getUrl());
    settings.put(Environment.USER, dbModel.getUser());
    settings.put(Environment.PASS, dbModel.getSecret());
    settings.put(Environment.SHOW_SQL, dbModel.getShowSql());
    settings.put(Environment.ENABLE_LAZY_LOAD_NO_TRANS, dbModel.getLazyLoad());
    
    // HikariCP连接池配置保持不变
    settings.put("hibernate.hikari.connectionTimeout", dbModel.getConnectionTimeout());
    settings.put("hibernate.hikari.idleTimeout", dbModel.getIdleTimeout());
    settings.put("hibernate.hikari.maxLifetime", dbModel.getMaxLifetime());
    settings.put("hibernate.hikari.autoCommit", dbModel.getAutoCommit());
    settings.put("hibernate.hikari.minimumIdle", dbModel.getMinimumIdle());
    settings.put("hibernate.hikari.maximumPoolSize", dbModel.getMaxPoolSize());
    settings.put("hibernate.hikari.registerMbeans", dbModel.getRegisterMbean());
    return settings;
}

分别配置两个数据库的DbModel

  • MySQL 5配置示例
    DbModel mysql5Db = new DbModel();
    mysql5Db.setDriver("com.mysql.cj.jdbc.Driver"); // 用8.x驱动的新类,兼容5
    mysql5Db.setDialect("org.hibernate.dialect.MySQL5Dialect");
    mysql5Db.setUrl("jdbc:mysql://your-mysql5-host:3306/dbname?useSSL=false");
    // 其他用户名、密码、连接池参数按需设置
    
  • MySQL 8配置示例
    DbModel mysql8Db = new DbModel();
    mysql8Db.setDriver("com.mysql.cj.jdbc.Driver");
    mysql8Db.setDialect("org.hibernate.dialect.MySQL8Dialect");
    mysql8Db.setUrl("jdbc:mysql://your-mysql8-host:3306/dbname?useSSL=false&serverTimezone=UTC");
    // 其他参数按需设置
    

4. 你的当前错误的直接原因

你设置了com.mysql.jdbc.Driver,但如果Maven实际加载的是8.0.21的驱动,虽然这个类存在,但它是一个过时的兼容类,可能会因为缺少时区配置(MySQL 8要求)或者类加载冲突导致初始化失败。修正驱动类为com.mysql.cj.jdbc.Driver,并为MySQL 8的URL添加时区参数,就能解决这个直接错误。


内容的提问来源于stack exchange,提问作者Nikolay

火山引擎 最新活动