【问题标题】:EntitityManager not injected properly, always nullEntityManager 未正确注入,始终为空
【发布时间】:2018-03-26 00:07:58
【问题描述】:

我有一些在 JAX-RS 方法中创建和持久化的 JPA 实体。我有一个工作线程,随着时间的推移处理有关 JPA 中这些实体的一些数据,虽然我可以传入 Entity 对象,但我无法保留对它们的任何更改,因为进行更改的线程中的 EntityManager 始终为空。

包含我的工作线程的类声明如下:

public final class EntityService {

@PersistenceContext(type = PersistenceContextType.EXTENDED)
EntityManager entityManager;

EntityManager 始终为 null,即使它是从 JAX-RS 方法传入的,当线程有机会尝试使用 EM 时,EM 也为 null,因为 JAX-RS 方法已终止。

当注入不起作用时,如何将有效的实体管理器添加到我的 Service pojo 中?我正在使用 Hibernate 和 Wildfly 10

【问题讨论】:

  • 您在保存方法中使用@Transactional 吗? EntityManager 不应该为空,你应该有问题是你的 spring 配置或者 bean 的加载方式
  • 我没有spring配置,我没用spring。是野蝇。此外,EntityService 类不是托管 bean。

标签: java multithreading hibernate jpa


【解决方案1】:

EntityService 需要被管理才能注入EntityManager。例如:添加@LocalBean注解,将EntityService注入REST服务类。

我也不确定创建class EntitySercice final 是否是个好主意。

【讨论】:

【解决方案2】:

持久化上下文

简而言之,您只能将EntityManager 注入EJB。 If you're EJB is not Stateful, it won't work with an EXTENDED persistence context。取而代之的是,你会选择一个跨界的:

@Stateless
public class myService{

    @PersistenceContext(type = PersistenceContextType.TRANSACTION)
    protected EntityManager em;

}

我没有尝试过this option,但您可以将您的 REST 资源注释为 Stateless,这将允许您注入 EntityManager

EntityManagerFactory

​​>

如果你不使用 EJB,那么你需要inject the EntityManagerFactory as shown in this answer:(下面是复制的代码)

package com.test.service;

import java.util.*;
import javax.persistence.*;
import javax.ws.rs.*;

@Path("/service")
public class TestService {

    @PersistenceUnit(unitName = "test")
    private EntityManagerFactory entityManagerFactory;

    @GET
    public List get() {
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        try {
            // do something with entityManager
        } finally {
            entityManager.close();
        }
    }
}

两个备注:

【讨论】:

    【解决方案3】:

    我遇到了这个问题,因为我在 pom.xml 中省略了 starter-parent

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
    </parent>
    

    虽然我使用的是PersistenceContextType.EXTENDED 而不是PersistenceContextType.TRANSACTION

    【讨论】: