EntityManager注入为空导致createQuery调用失败问题求助
解决方案:EntityManager注入null问题修复
问题根源
你在BookRepositoryImpl中使用@PersistenceContext注入EntityManager,但同时通过DbConfig中的@Produces方法手动创建了EntityManager实例。@PersistenceContext依赖容器从JPA持久化单元自动管理实体管理器,而自定义的Producer会干扰这种注入逻辑,导致容器无法正确注入EntityManager,最终出现null异常。
修复步骤
1. 修改BookRepositoryImpl的注入方式
将@PersistenceContext替换为@Inject,直接注入自定义Producer创建的EntityManager:
@ApplicationScoped public class BookRepositoryImpl implements BookRepository { @Inject // 替换@PersistenceContext为@Inject EntityManager entityManager; @Override public List<Book> findAll() { try { TypedQuery<Book> query = entityManager.createQuery("SELECT b FROM Book b ORDER BY b.id ASC", Book.class); return query.getResultList(); } catch (Exception e) { throw new RuntimeException(e); } } // 其他CRUD方法 }
2. 优化DbConfig的EntityManager Producer(可选但推荐)
确保EntityManagerFactory是单例的,避免重复创建资源浪费性能:
@ApplicationScoped public class DbConfig { @Inject @ConfigProperty(name = "db.connection.username") private String dbUser; @Inject @ConfigProperty(name = "db.connection.password") private String dbPassword; @Inject @ConfigProperty(name = "db.connection.url") private String dbUrl; private EntityManagerFactory emf; @PostConstruct void init() { Map<String, String> properties = new HashMap<>(); properties.put("javax.persistence.jdbc.url", dbUrl); properties.put("javax.persistence.jdbc.user", dbUser); properties.put("javax.persistence.jdbc.password", dbPassword); emf = Persistence.createEntityManagerFactory("persistence-books", properties); } @Produces @ApplicationScoped public EntityManager entityManager() { return emf.createEntityManager(); } @PreDestroy void destroy() { if (emf != null && emf.isOpen()) { emf.close(); } } }
3. 检查BookRest的依赖注入完整性
确保BookService被正确注入(代码中你省略了注入部分,需补充):
@ApplicationScoped @Path("/books") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public class BookRest { @Inject BookService bookService; // 补充BookService的注入 @GET public List<Book> findAll() { System.out.println("Buscando todos"); return bookService.findAll(); } // 其他CRUD方法 }
关键说明
@PersistenceContext适用于容器管理的JPA单元(通常配合persistence.xml配置),自定义Producer创建的EntityManager需用@Inject注入。- 所有需要依赖注入的类必须被CDI容器管理(标注
@ApplicationScoped等作用域注解)。 - 单例化
EntityManagerFactory能避免重复创建昂贵的工厂实例,提升应用性能。
内容的提问来源于stack exchange,提问作者Mermaid14
相关产品推荐
相关产品推荐

