将无状态 bean 注入到 ScheduledExecutorService 的可运行对象中

Inject stateless bean into runnable for ScheduledExecutorService

我想 运行 在部署 Glassfish 之后进行一些处理。进程将 运行 每小时进行一次,它包含通过无状态 bean CarService 和下面的 findAll() 从数据库 table 获取数据:

@PersistenceContext
private EntityManager em;

public List<Cars> findAll() {
    javax.persistence.criteria.CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
    cq.select(cq.from(Cars.class));
    return em.createQuery(cq).getResultList();
}

然后我在部署后使用 ScheduledExecutorService 启动进程。

@ManagedBean(eager=true)
@ApplicationScoped
public class ApplicationStateChange {

private ScheduledExecutorService scheduler;

@PostConstruct
public void init() {
    System.out.println("ejb init method called");
    scheduler = Executors.newScheduledThreadPool(2);
    scheduler.scheduleAtFixedRate(new ScheduleTask();, 15, 30, TimeUnit.SECONDS);
}

@PreDestroy
    public void destroy() {
        /* Shutdown stuff here */
        System.out.println("ejb destroy method called");
        scheduler.shutdownNow();
    }

上面的 ScheduleTask() 包含包含业务逻辑的流程,例如:

public class ScheduleTask implements Runnable {

    @Inject
    CarService carService;
    private volatile ScheduledExecutorService scheduler = null;

    @Override
    public void run() {
        System.out.println("scheduletask is called");
        List<Car> carList = new ArrayList<>();
               carList = carService.findAll();
        if (carList != null) {
            for (Car car : carList) {
                System.out.println(car);
            }
        }
    }

我无法通过注入上述 运行nable class 来获取 findALL() 方法。调度程序工作正常但是当它到达 carList = carService.findAll(); 时它失败了事实上它在 javax.persistence.criteria.CriteriaQuery cq = em.getCriteriaBuilder().createQuery();

失败了

我怀疑持久性上下文在调用时没有正确加载。

我已关注以下问题Spawning threads in a JSF managed bean for scheduled tasks using a timer

scheduledExecutorService, timerService and Stateless EJB on scheduled jobs

正如您所链接的第一个问题的答案中明确指出的那样,只需将 @Schedule 用于 @Singleton@Startup 注释的 SessionBean,以确保它在服务器运行时运行启动或部署应用程序。

正如您正确提到的,EntityManager 和 PersistenceContext 不能注入到非容器管理的 class(并且 Singleton SessionBean 是托管的 class)。

链接答案:

Spawning threads in a JSF managed bean for scheduled tasks using a timer