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

将EJB应用迁移至Spring时访问EntityManager触发空指针异常求助

问题诊断与解决方案

核心原因:Spring未正确托管DAO Bean或未完成JPA配置,导致EntityManager未被注入

以下是具体的排查和修复步骤:

  • 确保DAO被Spring容器托管并启用注解支持
    Spring只有在管理Bean实例时,才会处理@PersistenceContext和@Transactional注解:

    1. 在ExampleDAOBean类上添加Spring的@Repository注解(DAO层专用注解,自带异常转换功能);
    2. 在Spring的context.xml中配置组件扫描,确保能扫描到DAO所在包:
      <context:component-scan base-package="com.your.dao.package"/>
      
    3. 启用注解驱动的事务管理,同时确认@Transactional导入的是org.springframework.transaction.annotation.Transactional(而非EJB的同名注解):
      <tx:annotation-driven transaction-manager="transactionManager"/>
      
  • 添加Spring JPA核心配置,加载persistence.xml
    仅靠persistence.xml无法让Spring识别JPA配置,必须在context.xml中配置LocalContainerEntityManagerFactoryBean来加载指定的持久化单元:

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="PersonInfo"/>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
        </property>
    </bean>
    
  • 配置JTA事务管理器
    由于你的persistence-unit使用transaction-type="JTA",需要配置对应的JTA事务管理器:

    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="dataSource" ref="paymentsDS"/>
    </bean>
    

    同时确保paymentsDS数据源在Spring中正确定义,如果是应用服务器托管的数据源,通过JNDI lookup获取:

    <jee:jndi-lookup id="paymentsDS" jndi-name="paymentsDS" resource-ref="true"/>
    
  • 清理persistence.xml中的冗余配置
    移除tomee.jpa.cdi属性,这是TomEE的特定配置,在纯Spring环境中会干扰JPA处理:

    <!-- 移除这一行 -->
    <property name="tomee.jpa.cdi" value="false" />
    
  • 移除自定义EntityManager的getter/setter
    自定义的setEntityManager和getEntityManager可能干扰Spring的注入逻辑,直接使用@PersistenceContext注入的字段即可,无需额外封装:

    @Repository
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public class ExampleDAOBean implements IExampleDAOBean {
    
        @PersistenceContext(unitName = "PersonInfo")
        private EntityManager entityManager;
        
        @Override
        public List<PersonPersist> findAll(String sourceType) {
            List<PersonPersist> persistList = new ArrayList<>();
            try {
                Query query = entityManager.createNamedQuery(PersonPersist.FIND_ALL);
                persistList = (List<PersonPersist>) query.getResultList();
            } catch (NoResultException noResultException) {
            }
            return persistList;
        }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 05:31:19