2017-02-22 4 views
0

Je souhaite exécuter un processus juste après le déploiement de Glassfish. Processus se déroulera toutes les heures et il contient des données de la table DB fetching via CarService de haricot apatride findAll() ci-dessous:Injecter un bean sans état dans runnable pour ScheduledExecutorService

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

Puis j'utilise ScheduledExecutorService avec le processus démarre après le déploiement.

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

ci-dessus scheduleTask() contient le processus, y compris la logique métier par exemple:

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

je suis incapable d'obtenir la méthode findall() en injectant dans la classe ci-dessus runnable. planificateur fonctionne bien mais il échoue quand il atteint à carList = carService.findAll(); en fait son échec à javax.persistence.criteria.CriteriaQuery cq = em.getCriteriaBuilder().createQuery();

Je suspecte que le contexte de persistance n'est pas chargé correctement au moment de son appel.

J'ai suivi les questions suivantes Spawning threads in a JSF managed bean for scheduled tasks using a timer

scheduledExecutorService, timerService and Stateless EJB on scheduled jobs

Répondre

1

Comme il est clairement exposé dans la réponse à la première question que vous avez lié, il suffit d'utiliser @Schedule dans un @Singleton SessionBean annotées avec @Startup afin d'assurer qu'il fonctionne quand le serveur démarre ou l'application est déployée.

Comme vous l'avez correctement mentionné, EntityManager et PersistenceContext ne peuvent pas être injectés dans une classe non-conteneur-mananged (et Singleton SessionBean est une classe managée).

Linked Réponse:

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

+0

OK je peux avec le récipient géré '@Schedule' au lieu de ** ScheduledExecutorService ** mais maintenant je dois aborder avec la configuration de la minuterie GlassFish qui est douloureuse, car elle est la réponse ** 'Information: Il n'y a pas EJB Timers détenue par ce serveur Information: <== Timers Restored.' ** C'est la raison pour laquelle j'essayais d'utiliser ** ScheduledExecutorService ** qui exécutera le processus à la vitesse fixe en obtenant runnable la mise en oeuvre. Y a-t-il un moyen d'accrocher/injecter mon EntityManager dans runnable? –

+0

Non, vous ne pouvez pas injecter EntityManager dans une classe non gérée par un conteneur et vous devez éviter de gérer vous-même les tâches. En ce qui concerne la configuration de Timer dans Glassfish, c'est un bon point, mais c'est aussi une nouvelle question. Ouvrez une nouvelle question – perissf

+0

merci pour l'indice. J'ai testé mon gestionnaire d'entité avec le programmateur et fonctionne très bien. ce planificateur est identique à ScheduledExecutorService ?? signifie que les tâches s'exécuteront de manière asynchrone par un thread de travail, et non par le thread qui transmet la tâche au planificateur. sinon je dois gérer à nouveau toutes les tâches suivantes en utilisant ScheduledExecutorService pour chaque élément de ArrayList à partir de EntityManager –