You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 04:23:21