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

Apache Camel无法识别JpaComponent:找不到oldDealer的EntityManager持久化提供者

Apache Camel JpaComponent 报错「No Persistence provider for EntityManager named oldDealer」

问题场景

使用Apache Camel时遇到JpaComponent无法识别的问题,报错信息:

No Persistence provider for EntityManager named oldDealer

已通过@Autowired注入EntityManager并确认初始化完成,但Camel注册表中无法找到对应的持久化单元,且不想使用persistence.xml,希望仅通过application.properties完成配置。

相关配置与代码

application.properties

spring.datasource.olddealer.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.olddealer.jdbcUrl=jdbc:mariadb://10.0.0.222/dealer_cabinet
spring.datasource.olddealer.url=jdbc:mariadb://10.0.0.222/dealer_cabinet
spring.datasource.olddealer.username=dealer_cabinet
spring.datasource.olddealer.password=

spring.datasource.newdealer.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.newdealer.jdbcUrl=jdbc:mariadb://10.0.0.222/dealer
spring.datasource.newdealer.url=jdbc:mariadb://10.0.0.222/dealer
spring.datasource.newdealer.username=dealer_cabinet
spring.datasource.newdealer.password=

OldDealerConfiguration.java

@Configuration
@EnableJpaRepositories(
        entityManagerFactoryRef = OldDealerConfiguration.ENTITY_MANAGER_FACTORY,
        transactionManagerRef = OldDealerConfiguration.TRANSACTION_MANAGER,
        basePackages = OldDealerConfiguration.JPA_REPOSITORY_PACKAGE
)
public class OldDealerConfiguration {
    public static final String ENTITY_MANAGER_FACTORY = "oldDealerEntityManagerFactory";
    public static final String TRANSACTION_MANAGER = "oldDealerTransactionManager";
    public static final String JPA_REPOSITORY_PACKAGE = "com.flytech.camelrouter.repository.olddealer";


    @Bean(name = "oldDealerProperties")
    @Primary
    @ConfigurationProperties("spring.datasource.olddealer")
    DataSourceProperties oldDealerDataSourceProperties(){
        return new DataSourceProperties();
    }

    @Bean(name = "oldDealerDataSource")
    @Primary
    @ConfigurationProperties(prefix="spring.datasource.olddealer")
    public DataSource oldDealerDataSource(@Qualifier("oldDealerProperties") DataSourceProperties dataSourceProperties) {
        return dataSourceProperties.initializeDataSourceBuilder().build();
    }

    @Bean(name = ENTITY_MANAGER_FACTORY)
    public LocalContainerEntityManagerFactoryBean oldDealerEntityManagerFactoryBean(
            @Qualifier("oldDealerDataSource") DataSource dataSource){
        LocalContainerEntityManagerFactoryBean emfb = new LocalContainerEntityManagerFactoryBean();
        emfb.setPersistenceUnitName("oldDealer");
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setDatabasePlatform("org.hibernate.dialect.MariaDBDialect");
        emfb.setJpaVendorAdapter(vendorAdapter);
        emfb.setDataSource(dataSource);
        emfb.setPackagesToScan("com.flytech.camelrouter.entity.olddealer");
        emfb.afterPropertiesSet();
        return emfb;
    }

    @Bean(name = TRANSACTION_MANAGER)
    public PlatformTransactionManager oldDealerTransactionManager(
            @Qualifier(ENTITY_MANAGER_FACTORY) EntityManagerFactory entityManagerFactory){
        JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
        jpaTransactionManager.setEntityManagerFactory(entityManagerFactory);
        return jpaTransactionManager;
    }

    @Bean("oldDealerJpaComponent")
    public JpaComponent oldDealerJpaComponent(
            @Qualifier(OldDealerConfiguration.ENTITY_MANAGER_FACTORY)EntityManagerFactory entityManagerFactory,
            CamelContext camelContext){
        JpaComponent jpaComponent = new JpaComponent();
        jpaComponent.setEntityManagerFactory(entityManagerFactory);
        jpaComponent.setCamelContext(camelContext);
        return jpaComponent;
    }
}

(注:原代码中@org.apache.camel.language.bean.Bean注解为冗余配置,已移除)

SecondTestRouter.java

@Component
public class SecondTestRouter extends RouteBuilder {

    @Autowired
    @Qualifier("oldDealerJpaComponent")
    JpaComponent jpaComponent;

    @Autowired
    @PersistenceContext(unitName = "oldDealer")
    EntityManager oldEntityManager;

    @Autowired
    @PersistenceContext(unitName = "newDealer")
    EntityManager newEntityManager;

    @Override
    public void configure() throws Exception {
        from("timer://readDataFromOldDealer?period=60000")
                .to("jpa:com.flytech.camelrouter.entity.olddealer.Network?" +
                        "resultClass=com.flytech.camelrouter.entity.olddealer.Network&" +
                        "persistenceUnit=oldDealer&nativeQuery=SELECT n.dealer, n.network, n.location, n.benefit, n.prefix, n.cid, n.locality_id, u.full_name, u.email, u.phone FROM networks n INNER join user u on n.dealer = u.username;")
                .log("${body.dealer}");
    }
}

问题分析与解决方案

核心原因

路由中使用jpa:端点并指定persistenceUnit=oldDealer时,Camel会默认尝试从JPA全局持久化单元注册表(依赖persistence.xml的方式)查找,而非你通过Spring Bean配置的EntityManagerFactory。虽然你已创建自定义oldDealerJpaComponent,但路由未使用该实例,而是调用了Camel默认的JPA组件。

解决步骤

  1. 直接引用自定义JpaComponent实例
    修改路由代码,通过bean:前缀调用自定义组件并指定JPA操作参数:

    @Override
    public void configure() throws Exception {
        from("timer://readDataFromOldDealer?period=60000")
                .toD("bean:oldDealerJpaComponent?operation=findByNativeQuery&nativeQuery=SELECT n.dealer, n.network, n.location, n.benefit, n.prefix, n.cid, n.locality_id, u.full_name, u.email, u.phone FROM networks n INNER join user u on n.dealer = u.username;&resultClass=com.flytech.camelrouter.entity.olddealer.Network")
                .log("${body.dealer}");
    }
    
  2. 注册自定义组件为Camel端点前缀
    在oldDealerJpaComponent的Bean定义中,将组件添加到Camel上下文并指定自定义前缀:

    @Bean("oldDealerJpa")
    public JpaComponent oldDealerJpaComponent(
            @Qualifier(OldDealerConfiguration.ENTITY_MANAGER_FACTORY)EntityManagerFactory entityManagerFactory,
            CamelContext camelContext){
        JpaComponent jpaComponent = new JpaComponent();
        jpaComponent.setEntityManagerFactory(entityManagerFactory);
        camelContext.addComponent("oldDealerJpa", jpaComponent);
        return jpaComponent;
    }
    

    之后路由可直接使用自定义前缀调用:

    from("timer://readDataFromOldDealer?period=60000")
            .to("oldDealerJpa:com.flytech.camelrouter.entity.olddealer.Network?" +
                    "resultClass=com.flytech.camelrouter.entity.olddealer.Network&" +
                    "nativeQuery=SELECT n.dealer, n.network, n.location, n.benefit, n.prefix, n.cid, n.locality_id, u.full_name, u.email, u.phone FROM networks n INNER join user u on n.dealer = u.username;")
            .log("${body.dealer}");
    
  3. 验证EntityManagerFactory初始化
    可在oldDealerEntityManagerFactoryBean方法中添加日志,确认persistenceUnitName已正确设置为oldDealer,且EntityManagerFactory成功创建。

额外注意事项

  • 多数据源JPA环境下,@Primary注解需正确使用,确保Spring能识别默认的EntityManagerFactory,当前配置中oldDealer相关Bean的@Primary设置正确。
  • 存在多个EntityManagerFactory时,必须明确指定Camel JPA组件使用的实例,自定义JpaComponent是最可靠的方式。

内容的提问来源于stack exchange,提问作者Suleyman Batyrov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 23:02:14