Spring Boot启动时数据库连接ConcurrentModificationException异常问题
Spring升级与更换MariaDB驱动后启动异常解决方案
将Spring版本从1.5.6升级至2.7.9,同时替换数据库驱动为org.mariadb.jdbc.Driver(对应MariaDB 10.5.16)后,应用启动抛出如下异常:
java.util.ConcurrentModificationException: null at java.util.Hashtable$Enumerator.next(Hashtable.java:1387) at org.mariadb.jdbc.Configuration.mapPropertiesToOption(Configuration.java:611) at org.mariadb.jdbc.Configuration.parseInternal(Configuration.java:589) at org.mariadb.jdbc.Configuration.parse(Configuration.java:518) at org.mariadb.jdbc.Driver.connect(Driver.java:96) at org.mariadb.jdbc.Driver.connect(Driver.java:27) at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364) at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206) at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476) at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115) at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:181) at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:68) at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35) at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101) at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:272) at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:246) at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:223) at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:175) at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:295) at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:252) at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:223) at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:173) at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:127) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1460) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1494) at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) at com.iba.asokp.analitycs.Application.main(Application.java:15) 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.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) at org.springframework.boot.loader.Launcher.launch(Launcher.java:108) at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65)
当前application.properties配置:
# connection spring.notification.driver-class-name=org.mariadb.jdbc.Driver spring.notification.jdbc-url=jdbc:mariadb://${DB_CONNECTION_URL}:${DB_CONNECTION_PORT}/ibacontrol?autoReconnect=true&amp;useUnicode=true&amp;characterEncoding=utf8&amp;zeroDateTimeBehavior=convertToNull spring.notification.username=${DB_CONNECTION_USERNAME} spring.notification.password=${DB_CONNECTION_PASSWORD} spring.notification.name=ibacontrol spring.notification.maxActive=5 spring.notification.test-while-idle=true spring.notification.validation-query=SELECT 1 spring.notification.time-between-eviction-runs-millis=100000 spring.notification.min-evictable-idle-time-millis=10000 spring.data.jpa.repositories.enabled=false isnotify.enable=true url=jdbc:mariadb://${DB_CONNECTION_URL}:${DB_CONNECTION_PORT}/ibacontrol notificator.threadPool=100 reactor.threadPool=100 enabled=true server=server from=from login=login pass=pass
解决方案
- 升级MariaDB驱动版本:Spring Boot 2.7.x与MariaDB驱动2.7.x及以上版本兼容性更好,建议将
mariadb-java-client升级到2.7.x系列(如2.7.8),避免旧版本驱动内部遍历配置时的并发修改问题。 - 修正数据源配置参数:Spring Boot 2.x默认使用HikariCP,旧的
maxActive参数需替换为HikariCP标准参数maximum-pool-size;同时检查自定义数据源前缀spring.notification.*是否正确绑定到DataSource Bean,确保配置被正确识别。 - 修复JDBC URL转义问题:配置中的
&amp;是双重HTML转义,在application.properties中应直接使用&分隔参数,修改后的URL应为:jdbc:mariadb://${DB_CONNECTION_URL}:${DB_CONNECTION_PORT}/ibacontrol?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull。 - 删除冗余配置:移除独立的
url=jdbc:mariadb://...属性,该配置可能被驱动或Spring意外读取,导致配置冲突引发遍历异常。 - 开启驱动调试日志:若以上步骤无效,添加JVM启动参数
-Dorg.mariadb.jdbc.debug=true,查看驱动处理配置的详细日志,定位是否存在内部并发修改或系统属性被意外修改的情况。
内容的提问来源于stack exchange,提问作者NikiTer
相关产品推荐
相关产品推荐

