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

Spring Boot 3中手动创建Prototype对象致EntityManager为空问题

问题原因

你直接通过new FormGenerator()创建对象时,这个实例不在Spring容器的管控范围内,哪怕给类加了@Scope("prototype"),Spring也不会自动为它注入EntityManager——只有由Spring容器实例化的bean,才会触发依赖注入逻辑。

解决方法

方法1:通过ObjectProvider获取Spring管理的原型bean(推荐)

这是最符合Spring设计理念的方式,既能获取全新的原型实例,又能保证依赖自动注入。

  1. 给FormGenerator添加@Component注解,让Spring能扫描并管理它:
    @Component
    @Scope("prototype")
    public class FormGenerator {
        private int fieldCounter=0;
        @Autowired
        private EntityManager entityManager;
        ...
    }
    
  2. 在SchoolRepositoryCustomImpl中注入ObjectProvider<FormGenerator>,通过它获取新实例:
    @Repository
    public class SchoolRepositoryCustomImpl extends SimpleJpaRepository<School, Long> implements SchoolRepositoryCustom {
    
        private final ObjectProvider<FormGenerator> formGeneratorProvider;
    
        // 构造函数注入
        public SchoolRepositoryCustomImpl(JpaEntityInformation<School, Long> entityInformation, 
                                          EntityManager entityManager,
                                          ObjectProvider<FormGenerator> formGeneratorProvider) {
            super(entityInformation, entityManager);
            this.formGeneratorProvider = formGeneratorProvider;
        }
    
        @Override
        public List<School> advanceSearch(SchoolSearch search) {
            // 每次调用getObject()都会返回一个全新的FormGenerator实例
            FormGenerator qg = formGeneratorProvider.getObject();
            // 后续业务逻辑
        }
    }
    

方法2:通过ApplicationContext获取原型bean

和方法1类似,只是换用ApplicationContext直接获取bean:

@Repository
public class SchoolRepositoryCustomImpl extends SimpleJpaRepository<School, Long> implements SchoolRepositoryCustom {

    private final ApplicationContext applicationContext;

    public SchoolRepositoryCustomImpl(JpaEntityInformation<School, Long> entityInformation, 
                                      EntityManager entityManager,
                                      ApplicationContext applicationContext) {
        super(entityInformation, entityManager);
        this.applicationContext = applicationContext;
    }

    @Override
    public List<School> advanceSearch(SchoolSearch search) {
        // 获取全新的原型实例
        FormGenerator qg = applicationContext.getBean(FormGenerator.class);
        // 后续业务逻辑
    }
}

同样需要给FormGenerator添加@Component注解。

方法3:手动注入EntityManager(应急方案,不推荐)

如果不想让Spring完全管理FormGenerator,可以手动传递EntityManager:

  1. 在FormGenerator中添加setter方法:
    @Scope("prototype")
    public class FormGenerator {
        private int fieldCounter=0;
        private EntityManager entityManager;
    
        public void setEntityManager(EntityManager entityManager) {
            this.entityManager = entityManager;
        }
        ...
    }
    
  2. 在Repository中手动设置依赖:
    @Repository
    public class SchoolRepositoryCustomImpl extends SimpleJpaRepository<School, Long> implements SchoolRepositoryCustom {
    
        private final EntityManager entityManager;
    
        public SchoolRepositoryCustomImpl(JpaEntityInformation<School, Long> entityInformation, EntityManager entityManager) {
            super(entityInformation, entityManager);
            this.entityManager = entityManager;
        }
    
        @Override
        public List<School> advanceSearch(SchoolSearch search) {
            FormGenerator qg = new FormGenerator();
            qg.setEntityManager(entityManager);
            // 后续业务逻辑
        }
    }
    

这种方式绕过了Spring的依赖注入机制,仅适合临时应急,不推荐长期使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 20:20:18