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

多数据源场景下如何获取指定的EntityManager?

问题解决步骤

1. 先解决实体类识别问题

报错“Not an entity: class com.activiti.entities.alfresco.TClaimModel”说明你的TClaimModel没被JPA识别为实体,先检查这几点:

  • 类上是否加了@Entity注解,包路径是否正确;
  • 实体类是否在Spring的组件扫描范围内(Spring Boot项目),或者在persistence.xml的<class>标签里声明过;
  • 类必须是public修饰,且有无参构造方法(JPA强制要求)。

2. 获取指定数据库的EntityManager

因为项目配置了两个数据库,Spring会生成两个EntityManager实例,得明确指定要注入的那个:

方法一:用@PersistenceContext指定持久化单元名称

多数据源配置时,每个数据源对应一个持久化单元,注入时指定unitName即可:

@PersistenceContext(unitName = "alfrescoPersistenceUnit") // 替换成你的持久化单元名称
private EntityManager entityManager;

这里的unitName要和你配置LocalContainerEntityManagerFactoryBean时设置的persistenceUnitName一致。

方法二:@Autowired结合@Qualifier指定bean名称

Spring Boot多数据源配置下,每个EntityManager bean有对应名称,用@Qualifier精准指定:

@Autowired
@Qualifier("alfrescoEntityManager") // 替换成目标EntityManager的bean名称
private EntityManager entityManager;

bean名称一般是你配置LocalContainerEntityManagerFactoryBean时的方法名,或者手动设置的beanName。

方法三:通过EntityManagerFactory创建EntityManager

虽然EntityManagerFactory没有createQuery,但它可以生成EntityManager实例,先注入指定的工厂类再创建:

@Autowired
@Qualifier("alfrescoEntityManagerFactory")
private EntityManagerFactory entityManagerFactory;

// 使用时创建EntityManager
EntityManager entityManager = entityManagerFactory.createEntityManager();

注意:这种方式创建的EntityManager需要手动关闭(用完调用entityManager.close()),如果是Spring管理的事务场景,优先用前两种方法让Spring托管生命周期。

3. 动态过滤代码优化提示

解决EntityManager问题后,用Criteria API实现动态查询时,70个字段逐个判断太繁琐,可以用反射遍历实体字段自动生成查询条件,示例框架如下:

public List<TClaimModel> dynamicFilter(TClaimModel filter) {
    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<TClaimModel> cq = cb.createQuery(TClaimModel.class);
    Root<TClaimModel> root = cq.from(TClaimModel.class);
    
    List<Predicate> predicates = new ArrayList<>();
    // 反射遍历字段,自动添加非空条件
    for (Field field : TClaimModel.class.getDeclaredFields()) {
        field.setAccessible(true);
        try {
            Object value = field.get(filter);
            if (value != null) {
                if (value instanceof String) {
                    predicates.add(cb.like(root.get(field.getName()), "%" + value + "%"));
                } else {
                    predicates.add(cb.equal(root.get(field.getName()), value));
                }
            }
        } catch (IllegalAccessException e) {
            // 处理异常
        }
    }
    
    cq.where(cb.and(predicates.toArray(new Predicate[0])));
    return entityManager.createQuery(cq).getResultList();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 16:35:24