SpringBoot MariaDB多数据源Schema不自动生成、报Unknown entity错误
SpringBoot 2.7 多MariaDB数据源配置异常修复方案
问题场景
- 技术栈:SpringBoot 2.7.0、MariaDB 10.5、Spring Data JPA
- 配置目标:搭建两个独立数据源,分别存储
users库的用户数据、data库的业务数据 - 初始配置操作:
- 分别定义两个数据源的DataSource实例
- 为两个数据源单独配置
LocalContainerEntityManagerFactoryBean、JpaTransactionManager - 通过
@EnableJpaRepositories注解分别指定两个数据源的Repository扫描路径、实体类扫描包 - 配置Hibernate方言为
MariaDB103Dialect,设置ddl-auto=create、generate-ddl=true,期望自动生成Schema和表结构
初始运行异常
- 持久化user数据源下的
Privilege实体时抛出异常:java.lang.IllegalArgumentException: Unknown entity: it.unict.spring.application.persistence.model.user.Privilege,直接阻断应用部署 - 数据库不存在
data、users对应Schema时,系统不会自动创建Schema和关联数据表
调整配置后出现的新问题
后续做了如下配置调整:
- 为两个数据源分别添加独立的
HibernateJpaVendorAdapter,开启generateDdl配置 - 在JDBC连接URL中追加
createDatabaseIfNotExist=true参数
调整后虽然可以自动创建数据库,但执行数据插入操作时,所有字段写入null值,和代码中传入的预期值不符。
经排查实体类、Repository层代码无逻辑错误,问题根源为多数据源JPA配置存在疏漏。
根因定位与修复方案
问题1:Unknown entity 实体未识别异常
根因:配置LocalContainerEntityManagerFactoryBean时,仅通过@EnableJpaRepositories指定实体扫描包不生效,必须显式给对应EntityManagerFactory设置packagesToScan属性,指定该数据源关联的实体类包路径,否则Hibernate不会加载对应路径下的@Entity标注实体。
修复代码示例:
// user数据源EntityManager配置示例 @Bean @Primary public LocalContainerEntityManagerFactoryBean userEntityManager( DataSource userDataSource, HibernateJpaVendorAdapter userJpaVendorAdapter) { LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(userDataSource); // 必须显式指定实体扫描包,不能仅靠注解扫描逻辑 em.setPackagesToScan("it.unict.spring.application.persistence.model.user"); em.setJpaVendorAdapter(userJpaVendorAdapter); // 其余JPA属性配置 HashMap<String, Object> properties = new HashMap<>(); properties.put("hibernate.dialect", "org.hibernate.dialect.MariaDB103Dialect"); properties.put("hibernate.hbm2ddl.auto", "create"); em.setJpaPropertyMap(properties); return em; } // data数据源EntityManager配置同理,指定对应业务实体包路径即可
问题2:Schema无法自动创建异常
根因:
- JDBC连接URL未指定Schema时,
createDatabaseIfNotExist=true参数只会创建URL中显式声明的库,未声明则不会触发创建逻辑 - Hibernate的
ddl-auto仅能在已存在的Schema下创建表,不会自动创建库级别的Schema
修复配置:
在两个数据源的JDBC连接URL中明确指定要连接的库名,同时保留createDatabaseIfNotExist=true参数,示例:
# user数据源连接配置 spring.datasource.user.jdbc-url=jdbc:mariadb://127.0.0.1:3306/users?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf8&serverTimezone=UTC # data数据源连接配置 spring.datasource.data.jdbc-url=jdbc:mariadb://127.0.0.1:3306/data?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
问题3:插入数据全为null值异常
根因:两个数据源的HibernateJpaVendorAdapter被Spring上下文默认单例池复用,没有做独立配置,导致JPA属性映射、实体字节码增强逻辑错乱,实体字段值无法被正确识别持久化。
修复方案:
给两个数据源分别创建独立的HibernateJpaVendorAdapter实例,不要共用单例Bean,示例:
// user数据源独立JPA适配器 @Bean public HibernateJpaVendorAdapter userJpaVendorAdapter() { HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter(); adapter.setGenerateDdl(true); adapter.setDatabasePlatform("org.hibernate.dialect.MariaDB103Dialect"); return adapter; } // data数据源独立JPA适配器 @Bean public HibernateJpaVendorAdapter dataJpaVendorAdapter() { HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter(); adapter.setGenerateDdl(true); adapter.setDatabasePlatform("org.hibernate.dialect.MariaDB103Dialect"); return adapter; }
同时注意@EnableJpaRepositories注解必须明确绑定对应数据源的entityManagerFactoryRef和transactionManagerRef,示例:
// user数据源Repository配置 @Configuration @EnableJpaRepositories( basePackages = "it.unict.spring.application.persistence.repository.user", entityManagerFactoryRef = "userEntityManager", transactionManagerRef = "userTransactionManager" ) public class UserDatasourceConfig { // 对应DataSource、EntityManager、TransactionManager Bean定义 } // data数据源Repository配置 @Configuration @EnableJpaRepositories( basePackages = "it.unict.spring.application.persistence.repository.data", entityManagerFactoryRef = "dataEntityManager", transactionManagerRef = "dataTransactionManager" ) public class DataDatasourceConfig { // 对应DataSource、EntityManager、TransactionManager Bean定义 }
配置校验要点
- 两个数据源的配置类要避免被SpringBoot JPA自动配置类重复扫描,可在启动类排除
DataSourceAutoConfiguration、HibernateJpaAutoConfiguration默认自动配置 - 不要在全局application.properties中配置通用JPA参数,所有JPA属性要分别设置到对应数据源的
LocalContainerEntityManagerFactoryBean的JpaPropertyMap中,避免参数串用 - 给主数据源添加
@Primary注解,避免Spring启动时出现多Bean冲突报错
内容的提问来源于stack exchange,提问作者Discipulos
相关产品推荐
相关产品推荐

