Boa tarde, eu ejeto automáticamente o EntityManger com o vraptor:
private final EntityManagerFactory factory;
private EntityManager manager;
public CriadorDeEntityManager(EntityManagerFactory factory) {
this.factory = factory;
}
@PostConstruct
public void abre() {
this.manager = factory.createEntityManager();
}
public EntityManager getInstance() {
return this.manager;
}
@PreDestroy
public void fecha() {
this.manager.close();
}
e eu preciso fazer uma thread para executar em um determinhado horário, que vai chamar uma função no banco:
porém quando eu chamo ele diz que esta fechado, porque o vraptor abre e fecha automático.
a pergunta é como eu faço para resolver isso?
public void teste(){
repositoryCliente.atualizaCliente();
}
public class VerificaSituacaoCliente extends Thread{
public void run() {
while (true) {
LocalDateTime agora = new LocalDateTime();
if (agora.getHourOfDay() == 16) {
teste();
}
try {
Integer tempoMill = 50 * 60000;
Thread.sleep(tempoMill);
} catch (Exception e) {
IndexController.logger
.warn(MessageException.persistenceException
+ e.getMessage() + "), <b>Causa: </b> "
+ e.getCause());
}
}
}
}
......
public void atualizaCliente() {
String hql = " select coliseusys.bloqueia_cliente_data()";
//String hql = " from Cliente";
//manager = fac
//manager.getTransaction().begin();
try {
Query query = manager.createQuery(hql);
//query.executeUpdate();
//manager.getTransaction().commit();
query.getResultList();
//manager.close();
} catch (PersistenceException e) {
IndexController.logger.warn(MessageException.persistenceException
+ e.getMessage() + "), <b>Causa: </b> " + e.getCause());
}
}
Obrigado!
o melhor é essa task receber um entityManagerFactory e abrir e fechar o entityManager e as transações quando for apropriado.
Ok!, eu faço isso para criar a fábrica, como eu faço para passar essa factory para o meu metodo;
@Component
public class CriadorDeEntityManager implements ComponentFactory<EntityManager> {
private final EntityManagerFactory factory;
private EntityManager manager;
public CriadorDeEntityManager(EntityManagerFactory factory) {
this.factory = factory;
}
@PostConstruct
public void abre() {
this.manager = factory.createEntityManager();
}
public EntityManager getInstance() {
return this.manager;
}
@PreDestroy
public void fecha() {
this.manager.close();
}
}
eu tentei fazer isso: é assim:
public class VerificaSituacaoCliente extends Thread{
CriadorDeEntityManagerFactory factoryMng;
EntityManagerFactory factory = factoryMng.getInstance();
EntityManager manager = factory.createEntityManager();
public void run() {
while (true) {
LocalDateTime agora = new LocalDateTime();
if (agora.getHourOfDay() == 17) {
System.out.println("teste");
String hql = " select coliseusys.bloqueia_cliente_data()";
manager.getTransaction().begin();
try {
Query query = manager.createQuery(hql);
query.getResultList();
manager.close();
} catch (PersistenceException e) {
IndexController.logger.warn(MessageException.persistenceException
+ e.getMessage() + "), <b>Causa: </b> " + e.getCause());
}
}
try {
Integer tempoMill = 50 * 60000;
Thread.sleep(tempoMill);
} catch (Exception e) {
IndexController.logger
.warn(MessageException.persistenceException
+ e.getMessage() + "), <b>Causa: </b> "
+ e.getCause());
}
}
}
}
Da nulo.
java.lang.NullPointerException
br.com.coliseu.thread.VerificaSituacaoCliente.<init>(VerificaSituacaoCliente.java:20)
br.com.coliseu.controller.IndexController.index(IndexController.java:31)
provavelmente é pq ninguém preenche esse objeto:
CriadorDeEntityManagerFactory factoryMng;
eu tenho essa classe:
package br.com.coliseu.resources;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import br.com.caelum.vraptor.ioc.ApplicationScoped;
import br.com.caelum.vraptor.ioc.Component;
import br.com.caelum.vraptor.ioc.ComponentFactory;
@Component
@ApplicationScoped
public class CriadorDeEntityManagerFactory implements
ComponentFactory<EntityManagerFactory> {
private EntityManagerFactory factory;
/**
* A variavel boolean verificaStatusCliente, foi colocado no CriadorDeEntityManagerFactory,
* porque deve ser armazenada quando o servidor e reincioado, e utilizada para a execucao da thread
* que verifica a data de vencimento do cliente.
* */
public static boolean verificaStatusCliente;
@PostConstruct
public void abre() {
factory = Persistence.createEntityManagerFactory("Coliseu");
}
public EntityManagerFactory getInstance() {
return factory;
}
@PreDestroy
public void fecha() {
this.factory.close();
}
}
que é o VRaptor que instancia… mas a sua classe que estende Thread é você mesmo que instancia, então vc deveria passar pra ela um EntityManagerFactory no construtor (e vc pode receber esse EntityManagerFactory no construtor da classe que instancia a thread).
eu fiz isso:
private final EntityManagerFactory factory;
public IndexController(EntityManagerFactory factory) {
this.factory = factory;
}
@Restrito
@Get
@Path("/")
public void index() {
if(!CriadorDeEntityManagerFactory.verificaStatusCliente){
CriadorDeEntityManagerFactory.verificaStatusCliente = true;
VerificaSituacaoCliente verifica = new VerificaSituacaoCliente(factory);
verifica.start();
}
}
public class VerificaSituacaoCliente extends Thread{
private EntityManagerFactory factory;
//CriadorDeEntityManagerFactory factoryMng;
//EntityManagerFactory factory = Persistence.createEntityManagerFactory("Coliseu");
public VerificaSituacaoCliente(EntityManagerFactory factory) {
this.factory = factory;
}
EntityManager manager = factory.createEntityManager();
public void run() {
while (true) {
LocalDateTime agora = new LocalDateTime();
if (agora.getHourOfDay() == 17) {
System.out.println("teste");
String hql = " select coliseusys.bloqueia_cliente_data()";
manager.getTransaction().begin();
try {
Query query = manager.createQuery(hql);
query.getResultList();
manager.close();
} catch (PersistenceException e) {
IndexController.logger.warn(MessageException.persistenceException
+ e.getMessage() + "), <b>Causa: </b> " + e.getCause());
}
}
try {
Integer tempoMill = 50 * 60000;
Thread.sleep(tempoMill);
} catch (Exception e) {
IndexController.logger
.warn(MessageException.persistenceException
+ e.getMessage() + "), <b>Causa: </b> "
+ e.getCause());
}
}
}
}
e deu null ainda.
essa linha:
EntityManager manager = factory.createEntityManager();
tem que estar dentro do construtor… do jeito que está ela roda antes do construtor, portanto factory tá null.