Spring Boot从2.4.0升级到2.7.8后Hibernate Dialect异常求助
把Spring Boot版本从2.4.0升级至2.7.8后,出现如下异常:
java.util.ConcurrentModificationException stack-trace :- Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
使用数据库为MariaDB,已完成以下排查:
- 数据库名称、凭证及连接字符串均正常(降级回2.4.0版本可正常连接)
- 原版本配置文件无需额外添加方言配置
- 已在
@SpringBootApplication主类中排除自动配置类(因使用自定义数据源Bean) - 无法控制自定义数据源Bean的初始化方式(依赖由其他团队维护)
针对Spring Boot 2.7.x搭配自定义数据源时Hibernate方言检测出现的问题,可尝试以下方案:
1. 显式指定Hibernate方言
直接在配置文件中硬编码方言,跳过自动检测逻辑:
spring: jpa: properties: hibernate: dialect: org.hibernate.dialect.MariaDBDialect
若使用properties格式:
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
备注:如果你的MariaDB是10.2及以上版本,可使用
org.hibernate.dialect.MariaDB102Dialect,支持更多新版本特性。
2. 自定义EntityManagerFactory绑定数据源与Hibernate配置
由于无法修改数据源Bean的初始化逻辑,可通过自定义LocalContainerEntityManagerFactoryBean手动绑定数据源与Hibernate配置,确保Hibernate能获取到方言解析所需信息:
@Configuration public class JpaConfig { @Autowired private DataSource dataSource; @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource); // 替换为你的实体类所在包路径 em.setPackagesToScan("com.your.project.entity"); HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); vendorAdapter.setDatabasePlatform("org.hibernate.dialect.MariaDBDialect"); em.setJpaVendorAdapter(vendorAdapter); em.setJpaProperties(getHibernateProperties()); return em; } private Properties getHibernateProperties() { Properties props = new Properties(); // 可添加其他Hibernate配置,如是否显示SQL props.setProperty("hibernate.show_sql", "false"); return props; } }
该配置会覆盖默认JPA自动配置,确保Hibernate初始化时能正确关联数据源,避免DialectResolutionInfo为空的问题。
3. 检查自动配置排除是否完整
若之前只排除了部分自动配置类,可能导致Hibernate相关配置缺失。需确保同时排除DataSourceAutoConfiguration和HibernateJpaAutoConfiguration:
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class}) public class YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } }
同时注意自定义数据源的初始化时机,避免Hibernate初始化时数据源未就绪(这也可能是ConcurrentModificationException的诱因)。
4. 排查依赖冲突
Spring Boot 2.7.8对应的Hibernate版本为5.6.x,可通过依赖树检查是否存在其他团队维护的依赖引入了不同版本的Hibernate或JDBC驱动,导致版本冲突:
- Maven执行:
mvn dependency:tree - Gradle执行:
./gradlew dependencies
找到冲突依赖后进行排除处理即可。
最直接的解决方案是显式指定Hibernate方言,绕开自动检测的问题;若该方案无效,再尝试自定义EntityManagerFactoryBean绑定配置,同时检查自动配置排除是否彻底、是否存在依赖冲突。
内容的提问来源于stack exchange,提问作者omarAhmed

