Spring Boot JPA配置双Oracle数据源报错:找不到EntityManagerFactoryBuilder
Spring Boot JPA多Oracle数据源配置报错排查
报错信息
PCPDatabaseConfig required a bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' that could not be found.
问题根源及修复步骤
1. 缺失EntityManagerFactoryBuilder Bean
自定义多数据源JPA配置时,Spring Boot自动配置逻辑不会自动生成EntityManagerFactoryBuilder,必须手动在配置类中定义该Bean。
2. @EnableJpaRepositories未指定关联实例
多数据源场景下,@EnableJpaRepositories必须明确指定对应的entityManagerFactoryRef和transactionManagerRef,否则会导致Spring无法区分不同数据源的实例。
3. JpaVendorAdapter未注册为Spring Bean
PCPDatabaseConfig中的jpaVendorAdapterOraclePCP()方法缺少@Bean注解,导致Spring无法识别并管理该实例。
4. 持久化单元名称重复
两个数据源配置的persistenceUnit均设为"oracle",需分别命名避免冲突。
修复后的完整配置代码
PCPDatabaseConfig
@Configuration @EnableTransactionManagement @EnableJpaRepositories( basePackages = "com.xxx.repository.pcp", entityManagerFactoryRef = "entityManagerFactoryPCP", transactionManagerRef = "oraclesqlTransactionManagerPCP" ) public class PCPDatabaseConfig { @Primary @Bean @ConfigurationProperties(prefix = "spring.datasource.pcp") public DataSource pcpDataSource() { return DataSourceBuilder.create().build(); } @Primary @Bean public JdbcTemplate pcpJdbcTemplate(@Qualifier("pcpDataSource") DataSource pcpDataSource) { return new JdbcTemplate(pcpDataSource); } @Bean @ConfigurationProperties(prefix = "spring.jpa") public JpaVendorAdapter jpaVendorAdapterOraclePCP() { return new HibernateJpaVendorAdapter(); } @Bean public EntityManagerFactoryBuilder entityManagerFactoryBuilder() { return new EntityManagerFactoryBuilder(jpaVendorAdapterOraclePCP(), new HashMap<>(), null); } @Primary @Bean(name = "entityManagerFactoryPCP") public LocalContainerEntityManagerFactoryBean entityManagerFactoryPCP(EntityManagerFactoryBuilder builder) { return builder .dataSource(pcpDataSource()) .packages("com.xxx.model.pcp") // 注意:此处应为实体类包路径,而非Repository包 .persistenceUnit("pcpPersistenceUnit") .build(); } @Primary @Bean(name = "oraclesqlTransactionManagerPCP") public PlatformTransactionManager oraclesqlTransactionManagerPCP(@Qualifier("entityManagerFactoryPCP") EntityManagerFactory entityManagerFactory) { return new JpaTransactionManager(entityManagerFactory); } }
PPDatabaseConfig
@Configuration @EnableTransactionManagement @EnableJpaRepositories( basePackages = "com.xxx.repository.pp", entityManagerFactoryRef = "entityManagerFactoryPP", transactionManagerRef = "oraclesqlTransactionManagerPP" ) public class PPDatabaseConfig { @Bean @ConfigurationProperties(prefix = "spring.datasource.pp") public DataSource ppDataSource() { return DataSourceBuilder.create().build(); } @Bean public JdbcTemplate ppJdbcTemplate(@Qualifier("ppDataSource") DataSource ppDataSource) { return new JdbcTemplate(ppDataSource); } @Bean @ConfigurationProperties(prefix = "spring.jpa") public JpaVendorAdapter jpaVendorAdapterOraclePP() { return new HibernateJpaVendorAdapter(); } @Bean public EntityManagerFactoryBuilder entityManagerFactoryBuilderPP() { return new EntityManagerFactoryBuilder(jpaVendorAdapterOraclePP(), new HashMap<>(), null); } @Bean(name = "entityManagerFactoryPP") public LocalContainerEntityManagerFactoryBean entityManagerFactoryPP(@Qualifier("entityManagerFactoryBuilderPP") EntityManagerFactoryBuilder builder) { return builder .dataSource(ppDataSource()) .packages("com.xxx.model.pp") // 注意:此处应为实体类包路径,而非Repository包 .persistenceUnit("ppPersistenceUnit") .build(); } @Bean(name = "oraclesqlTransactionManagerPP") public PlatformTransactionManager oraclesqlTransactionManagerPP(@Qualifier("entityManagerFactoryPP") EntityManagerFactory entityManagerFactory) { return new JpaTransactionManager(entityManagerFactory); } }
额外注意事项
packages()方法需传入实体类所在包路径,而非Repository包,否则JPA无法扫描到实体类。- 若两个数据源JPA配置一致,可共享同一个
EntityManagerFactoryBuilderBean,无需重复定义。 - 建议在application.yml中补充JPA核心配置:
spring: jpa: hibernate: ddl-auto: none show-sql: false properties: hibernate: dialect: org.hibernate.dialect.Oracle12cDialect
内容的提问来源于stack exchange,提问作者Tohid Makari
相关产品推荐
相关产品推荐

