Spring Boot整合Camel与JPA多数据源场景下无法找到指定持久化单元问题排查
我一眼就看出你遇到的核心问题是Camel没法通过persistenceUnit名称正确匹配到对应的数据源,报错javax.persistence.PersistenceException: No Persistence provider for EntityManager named domain。结合你的配置代码,我整理了几个关键修复点:
1. 移除EntityManagerFactory Bean上的@PersistenceContext注解
你在domainEntityManager和lookupEntityManager方法上加了@PersistenceContext(unitName = "xxx"),这个注解是用来注入EntityManager的,不是用来定义EntityManagerFactory Bean的,属于误用。直接删掉这个注解就行,LocalContainerEntityManagerFactoryBean本身已经通过setPersistenceUnitName()方法正确标识了持久化单元名称。
修改后的domainEntityManager方法示例:
@Bean @Primary public LocalContainerEntityManagerFactoryBean domainEntityManager() { final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(domainDataSource()); em.setPackagesToScan("com.myapp.model.domain","com.myapp.legacy"); em.setPersistenceProviderClass(HibernatePersistenceProvider.class); em.setPersistenceUnitName("domain"); // 这里已经正确设置了持久化单元名 final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); em.setJpaVendorAdapter(vendorAdapter); final HashMap<String, Object> properties = new HashMap<String, Object>(); properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); properties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect"); em.setJpaPropertyMap(properties); return em; }
2. 在Camel路由中直接引用EntityManagerFactory Bean
在Spring多数据源环境下,Camel的JPA组件有时没法仅通过persistenceUnit参数正确定位到对应的EntityManagerFactory(尤其是没有传统persistence.xml文件的情况下)。更可靠的方式是直接指定Spring容器中EntityManagerFactory的Bean名称,用entityManagerFactory参数:
修改你的Camel路由片段:
.to("jpa:com.myapp.model.domain.Event?entityType=java.util.ArrayList&entityManagerFactory=#domainEntityManager")
这里的#domainEntityManager就是你在配置类中定义的EntityManagerFactory Bean的名称,确保和@Bean方法名一致就行(也可以给@Bean指定name属性)。
3. 验证事务管理器的关联是否正确
虽然你已经为每个数据源配置了独立的事务管理器,但要确保Camel路由操作对应数据源时用对了事务管理器。如果路由涉及事务,可以通过transactionManager参数指定:
.to("jpa:com.myapp.model.domain.Event?entityType=java.util.ArrayList&entityManagerFactory=#domainEntityManager&transactionManager=#domainTransactionManager")
4. 检查数据源配置的前缀是否匹配
确认database.properties里的配置前缀和@ConfigurationProperties的前缀完全一致:
- 主数据源前缀是
spring.datasource,对应配置文件里的spring.datasource.url、spring.datasource.username等 - 第二个数据源前缀是
spring.currency-datasource,对应配置文件里的spring.currency-datasource.url等
做完这些修改后重启服务,应该就能解决Camel找不到指定持久化单元的问题了。
内容的提问来源于stack exchange,提问作者karazy

