我想在部署Glassfish之后运行一些流程。进程将每小时运行一次,它包含通过无状态bean CarService从DB表中获取数据,并使用下面的findAll():
@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);
}
}
}
我无法通过注入上面的runnable类来获取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
答案 0 :(得分:1)
正如您已链接的第一个问题的答案中明确公开的那样,只需将@Schedule
用于@Singleton
使用@Startup
注释的SessionBean,以确保它在服务器启动时运行或应用程序已部署。
正如您正确提到的,EntityManager和PersistenceContext不能注入非容器管理类(而Singleton SessionBean是托管类)。
链接答案:
Spawning threads in a JSF managed bean for scheduled tasks using a timer