多数据源配置下如何指定使用次级数据库的EntityManagerFactory
多数据源下引用次级数据库EntityManagerFactory的问题解决
配置多数据源后,尝试使用次级数据库的EntityManagerFactory时,系统总是自动引用主数据库的配置,导致报错“Not an Entity”。以下是相关配置信息:
application.properties
spring.ds.datasource1.url=jdbc:postgresql:x spring.ds.datasource1.username=user spring.ds.datasource1.password= spring.ds.datasource2.url=jdbc:postgresql:x spring.ds.datasource2.username=user spring.ds.datasource2.password=
Datasource 1 配置
@EnableJpaRepositories(basePackages = "eu.example", entityManagerFactoryRef = "ds1EntityManagerFactory", transactionManagerRef = "ds1TransactionManager") @Configuration public class Ds1DataSourceConfiguration { private static final String DS1_ENTITY_MANAGER_FACTORY = "ds1EntityManagerFactory"; private static final String DS1_TRANSACTION_MANAGER = "ds1TransactionManager"; @Primary @Bean @ConfigurationProperties(prefix = "spring.ds.datasource1") public DataSourceProperties ds1DataSourceProperties() { return new DataSourceProperties(); } @Primary @Bean @ConfigurationProperties("spring.ds.datasource1") public DataSource ds1DataSource(DataSourceProperties properties) { return properties .initializeDataSourceBuilder() .build(); } @Primary @Bean(name = DS1_ENTITY_MANAGER_FACTORY) public LocalContainerEntityManagerFactoryBean ds1EntityManagerFactoryBean( EntityManagerFactoryBuilder factoryBuilder, DataSource ds1Ds) { return factoryBuilder .dataSource(ds1Ds) .packages("eu.example.domain.entity.ds1") .build(); } @Primary @Bean(name = DS1_TRANSACTION_MANAGER) public PlatformTransactionManager ds1TransactionManager( @Qualifier(DS1_ENTITY_MANAGER_FACTORY) LocalContainerEntityManagerFactoryBean managerFactoryBean) { JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(); jpaTransactionManager.setEntityManagerFactory(managerFactoryBean.getObject()); return jpaTransactionManager; } }
Datasource 2 配置
与上述Ds1配置结构一致,但未添加@Primary注解。
当前Service类
@Service public class TestService{ private final EntityManagerFactory et2; // 业务方法... }
解决方案
要正确注入次级数据库的EntityManagerFactory,只需两步:
确认次级数据源EntityManagerFactory的Bean名称
在Ds2的配置类中,确保EntityManagerFactory的Bean有明确的唯一名称,同时指定对应实体类的包路径:// Ds2配置类中的EntityManagerFactory Bean定义 @Bean(name = "ds2EntityManagerFactory") public LocalContainerEntityManagerFactoryBean ds2EntityManagerFactoryBean( EntityManagerFactoryBuilder factoryBuilder, DataSource ds2Ds) { return factoryBuilder .dataSource(ds2Ds) .packages("eu.example.domain.entity.ds2") .build(); }这里的
name属性值ds2EntityManagerFactory是核心标识,需保证与Ds1的Bean名称不重复。在Service中通过@Qualifier指定要注入的Bean
由于Spring容器中存在两个EntityManagerFactory类型的Bean,且Ds1的Bean带有@Primary注解,默认会优先注入主库实例。必须通过@Qualifier注解明确指定次级库的Bean名称:@Service public class TestService{ private final EntityManagerFactory et2; // 构造方法注入(推荐方式) public TestService(@Qualifier("ds2EntityManagerFactory") EntityManagerFactory et2) { this.et2 = et2; } }
这样就能确保注入的是次级数据库对应的EntityManagerFactory,避免因默认选择主库而导致的“Not an Entity”错误。
内容的提问来源于stack exchange,提问作者Minez97
相关产品推荐
相关产品推荐

