2017-02-22 94 views
0

我想在部署Glassfish后立即运行一些进程。进程将运行每隔一小时,它包含通过无状态Bean CarService用的findAll(从数据库表中读取数据)表示:将无状态bean注入到ScheduledExecutorService的runnable中

@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()包含包括业务逻辑e.g过程:

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); 
      } 
     } 
    } 

我无法通过注入到上述可运行类来获得的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

回答

1

可以清楚地暴露在回答对你有联系的第一个问题,只需使用@Schedule@Singleton的SessionBean标注有@Startup,以确保它运行时服务器启动或部署应用程序。

正如你正确的提到的,EntityManager和PersistenceContext不能被注入到一个非容器管理类(而Singleton SessionBean是一个托管类)。

链接答:

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

+0

OK,我可以和容器管理“@Schedule”,而不是** ** ScheduledExecutorService的,但现在我有GlassFish中的计时器配置是痛苦的,因为它解决正在回复**'信息:这台服务器没有EJB定时器 信息:<==定时器已恢复。'**这就是我试图使用**的原因** ScheduledExecutorService **,它将通过获得可运行的实现。有没有什么办法钩住/注入我的EntityManager在可运行? –

+0

不,你不能将EntityManager注入非容器管理的类,你应该避免自己管理任务。关于如何在GlassFish中配置Timer,这是一个很好的观点,但这也是一个新问题。打开一个新问题。 – perissf

+0

感谢您的提示。我已经使用调度程序测试了我的实体管理器,并且工作正常。这个调度程序与ScheduledExecutorService相同吗?意味着任务将由工作线程异步执行,而不是由将任务交给调度程序的线程执行。否则我必须通过使用ScheduledExecutorService对EntityManager的ArrayList的每个元素再次管理所有后续任务 –