定义EntityManagerFactory后实体自动创建失效问题排查
Spring 2.7.13 多数据源配置后JPA实体无法自动创建问题排查
问题背景
原本运行正常的Spring-JPA项目,添加多数据源配置类后,实体对应的数据库表无法自动创建,也不被应用识别。项目基于Spring父版本2.7.13,升级至Spring 3.1.3后问题自动消失。已确认实体包路径配置正确,添加多数据源配置前功能完全正常。
使用的多数据源配置类代码如下:
@Configuration public class DataSourceConfig { // Primary datasource configuration @Primary @Bean(name = "primaryDataSource") @ConfigurationProperties(prefix = "spring.datasource") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Primary @Bean(name = "entityManagerFactory") public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("primaryDataSource") DataSource dataSource) { return builder .dataSource(dataSource) .packages("com.example.demo.model") // base package for your JPA entities .persistenceUnit("primary") .build(); } @Primary @Bean(name = "transactionManager") public PlatformTransactionManager transactionManager(@Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory) { return new JpaTransactionManager(entityManagerFactory); } // Secondary Datasource 1 Configuration @Bean(name = "secondaryDataSource") @ConfigurationProperties(prefix = "spring.ds1") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "secondaryJdbcTemplate") public JdbcTemplate secondaryJdbcTemplate(@Qualifier("secondaryDataSource") DataSource dataSource) { return new JdbcTemplate(dataSource); } // Secondary Datasource 2 Configuration @Bean(name = "thirdDataSource") @ConfigurationProperties(prefix = "spring.ds2") public DataSource thirdDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "thirdJdbcTemplate") public JdbcTemplate thirdJdbcTemplate(@Qualifier("thirdDataSource") DataSource dataSource) { return new JdbcTemplate(dataSource); } }
问题原因
Spring 2.7.x版本中,手动定义LocalContainerEntityManagerFactoryBean时,不会自动继承Spring Boot的JPA自动配置属性(如spring.jpa.hibernate.ddl-auto这类控制表生成策略的配置)。而Spring 3.x版本针对多数据源场景优化了自动配置逻辑,会自动传递这些属性到自定义的EntityManagerFactory中,因此升级后问题消失。
你的配置类仅指定了数据源和实体扫描包,但未显式绑定JPA相关配置,导致Spring 2.7.x无法触发Hibernate的DDL自动生成逻辑,进而无法创建实体对应的数据库表。
修复方案
方案1:通过JpaProperties绑定自动配置属性
在entityManagerFactory方法中注入JpaProperties,将Spring Boot配置文件中的JPA属性传递给EntityManagerFactory构建器:
@Primary @Bean(name = "entityManagerFactory") public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("primaryDataSource") DataSource dataSource, JpaProperties jpaProperties) { return builder .dataSource(dataSource) .packages("com.example.demo.model") .persistenceUnit("primary") .properties(jpaProperties.getProperties()) // 绑定配置文件中的JPA属性 .build(); }
方案2:显式设置Hibernate DDL策略
若仅需解决表创建问题,可直接在构建器中指定Hibernate的DDL相关属性:
@Primary @Bean(name = "entityManagerFactory") public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("primaryDataSource") DataSource dataSource) { Map<String, Object> hibernateProps = new HashMap<>(); hibernateProps.put("hibernate.hbm2ddl.auto", "update"); // 根据需求选择create/update/create-drop/validate hibernateProps.put("hibernate.show_sql", "true"); // 可选,用于SQL调试 return builder .dataSource(dataSource) .packages("com.example.demo.model") .persistenceUnit("primary") .properties(hibernateProps) .build(); }
额外注意事项
- 确保配置文件(
application.properties/application.yml)中存在正确的JPA配置,例如:spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true - 若项目中使用了
@EnableJpaRepositories,需确认其entityManagerFactoryRef属性指向的是你配置的primaryEntityManagerFactory实例,避免引用错误导致实体不被识别。
内容的提问来源于stack exchange,提问作者Amol
相关产品推荐
相关产品推荐

