Entitymanager fechado

3 respostas
M

Bom primeiramente tenho que dizer que não é a primeira vez que posto essa pergunta aqui, no entanto como aqui no meu serviço as prioridades mudam constantemente acabei deixando de lado, mas agora que to com mais tempo gostaria de resolver esse problema.
É o seguinte, estou desenvolvendo um EJB que faz parte de um sistema de middleware de localização, estou utilizando JPA, maven e o servidor de aplicação glassfish, meu serviço faz uma coisa bem simples, recebe requisições de clientes pedindo pela localização de um ou mais veículos através de uma lista de id’s. Ele pesquisa na base de dados, encontra as ultimas posições dos veículos constrói uma lista de posições e retorna para o cliente. Diga-se de passagem q tudo isso funciona, mas não perfeitamente.
O problema é esse, quando meu cliente requisita ao EJB ele retorna o resultado corretamente sem problemas, da primeira vez, se o mesmo cliente faz outra requisição dai acontece o problema ele gera uma exception gigantesca, o causedby no log do glassfish é o seguinte

java.lang.IllegalStateException: Attempting to execute an operation on a closed EntityManager.

Em outras palavras quando o bean alocado para atender a primeira requisição termina o EntityManager é fechado, e quando o cliente tenta chamar de novo o mesmo o bean o conteiner tenta usar a referencia antiga do entitymanager. Dessa forma da essa exception, dai se executo uma terceira vez da certo, uma quarta exception, e assim por diante. Aqui no meu serviço isso já até virou piada como o problema das requisições pares e impares, nas impares da certo nas pares da pau.
Eu tinha conseguido resolver esse problema com a anotação TransactionAttribute, ia lá setava um daqueles possíveis tipos de TransactionAttributeType: required, required_new, supports, not_supports, mandatory, never. Bom mas qual o problema, o problema é que essa “solução”, é dependente de como funciona essa comunicação. Tipo se a comunicação acontece entre o meu servidor e um cliente em outro glassfish remoto o TransactionAttributeType é de um tipo, se acontece entre um cliente local é outro tipo de TransactionAttributeType e assim por diante.
Afim de não manter uma comunicação tabajara como essa vim aqui perguntar para aqueles que tem mais experiencia , como posso resolver esse problema, o que estou fazendo de errado para acontecer isso, ou pelo menos o que deveria ser mais estudado para resolver o problema.
Abaixo segue o trecho de código que gera o erro, e é claro o erro propriamente dito, desde já agradeço pela atenção:

@Stateless(name=LocationServiceBean , mappedName=ejb/LocationServiceBean)

@TransactionAttribute(TransactionAttributeType.SUPPORTS)

public class LocationServiceBean implements LocationServiceRemote, LocationServiceLocal {
@PersistenceContext(unitName = "sdl", type=PersistenceContextType.TRANSACTION)
private EntityManager em;
private Query simpleQuery;
private Query historyQuery;


public LocationServiceBean() {
}

public LocationServiceBean(EntityManager em) {
    this.em = em;
}


//Codigo para a requisição de posição
private Query createQueryFindByDeviceId() {
    return em.createQuery("SELECT p FROM Notification p WHERE p.gid=:id" +
            " ORDER BY p.inferredAt DESC");
}

private Query getQueryFindByDeviceId() {
    if (simpleQuery == null) {
        simpleQuery = createQueryFindByDeviceId();
    }
    return simpleQuery;
}

@Override
public List<PositionNotification> getLocation(List<String> ids) {
    if (ids == null) {
        throw new IllegalArgumentException();
    }
    List<PositionNotification> list = new ArrayList<PositionNotification>();
    simpleQuery = getQueryFindByDeviceId();
    simpleQuery.setMaxResults(1);

    for (String id : ids) {

        simpleQuery.setParameter("id", id);
        List result = simpleQuery.getResultList();
       
        if (result.size() > 0) {
            PositionNotification position = (PositionNotification) result.get(0);

            if (position != null) {
                list.add(position);
            }
        }
    }
    return list;
}

O erro é o seguinte:

Exception thrown from bean; nested exception is: java.lang.IllegalStateException: Attempting to execute an operation on a closed EntityManager. java.lang.IllegalStateException: Attempting to execute an operation on a closed EntityManager. at org.eclipse.persistence.internal.jpa.EntityManagerImpl.verifyOpen(EntityManagerImpl.java:1210) at org.eclipse.persistence.internal.jpa.EJBQueryImpl.setMaxResults(EJBQueryImpl.java:833) at br.ufg.inf.lbs.sdl.LocationServiceBean.getLocation(LocationServiceBean.java:77) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.sun.enterprise.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1011) at com.sun.enterprise.security.SecurityUtil.invoke(SecurityUtil.java:175) at com.sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer.java:2920) at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4011) at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:203) at com.sun.ejb.containers.EJBObjectInvocationHandlerDelegate.invoke(EJBObjectInvocationHandlerDelegate.java:77) at $Proxy135.getLocation(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke(ReflectiveTie.java:154) at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:687) at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:227) at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1846) at com.sun.corba.ee.impl.protocol.SharedCDRClientRequestDispatcherImpl.marshalingComplete(SharedCDRClientRequestDispatcherImpl.java:183) at com.sun.corba.ee.impl.protocol.CorbaClientDelegateImpl.invoke(CorbaClientDelegateImpl.java:219) at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:192) at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.invoke(StubInvocationHandlerImpl.java:152) at com.sun.corba.ee.impl.presentation.rmi.bcel.BCELStubBase.invoke(BCELStubBase.java:225) at br.ufg.inf.lbs.sdl.__LocationServiceRemote_Remote_DynamicStub.getLocation(br/ufg/inf/lbs/sdl/__LocationServiceRemote_Remote_DynamicStub.java) at br.ufg.inf.lbs.sdl._LocationServiceRemote_Wrapper.getLocation(br/ufg/inf/lbs/sdl/_LocationServiceRemote_Wrapper.java) at br.ufg.inf.lbs.remoteclient.MiddlewareConnection.connectorToMiddlewareByLookup(MiddlewareConnection.java:55) at br.ufg.inf.lbs.remoteclient.SessionToMiddlewareConnectionBean.connect(SessionToMiddlewareConnectionBean.java:15) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.sun.enterprise.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1011) at com.sun.enterprise.security.SecurityUtil.invoke(SecurityUtil.java:175) at com.sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer.java:2920) at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4011) at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:203) at com.sun.ejb.containers.EJBObjectInvocationHandlerDelegate.invoke(EJBObjectInvocationHandlerDelegate.java:77) at $Proxy139.connect(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke(ReflectiveTie.java:154) at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:687) at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:227) at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1846) at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:1706) at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:1088) at com.sun.corba.ee.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:223) at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:806) at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.dispatch(CorbaMessageMediatorImpl.java:563) at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.doWork(CorbaMessageMediatorImpl.java:2567) at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:555) javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean; nested exception is: java.lang.IllegalStateException: Attempting to execute an operation on a closed EntityManager. at com.sun.ejb.containers.BaseContainer.checkExceptionClientTx(BaseContainer.java:3753) at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:3601) at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1379) at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1316) at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:210) at com.sun.ejb.containers.EJBObjectInvocationHandlerDelegate.invoke(EJBObjectInvocationHandlerDelegate.java:77) at $Proxy135.getLocation(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke(ReflectiveTie.java:154) at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:687) at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:227) at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1846) at com.sun.corba.ee.impl.protocol.SharedCDRClientRequestDispatcherImpl.marshalingComplete(SharedCDRClientRequestDispatcherImpl.java:183) at com.sun.corba.ee.impl.protocol.CorbaClientDelegateImpl.invoke(CorbaClientDelegateImpl.java:219) at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:192) at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.invoke(StubInvocationHandlerImpl.java:152) at com.sun.corba.ee.impl.presentation.rmi.bcel.BCELStubBase.invoke(BCELStubBase.java:225) at br.ufg.inf.lbs.sdl.__LocationServiceRemote_Remote_DynamicStub.getLocation(br/ufg/inf/lbs/sdl/__LocationServiceRemote_Remote_DynamicStub.java) at br.ufg.inf.lbs.sdl._LocationServiceRemote_Wrapper.getLocation(br/ufg/inf/lbs/sdl/_LocationServiceRemote_Wrapper.java) at br.ufg.inf.lbs.remoteclient.MiddlewareConnection.connectorToMiddlewareByLookup(MiddlewareConnection.java:55) at br.ufg.inf.lbs.remoteclient.SessionToMiddlewareConnectionBean.connect(SessionToMiddlewareConnectionBean.java:15) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.sun.enterprise.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1011) at com.sun.enterprise.security.SecurityUtil.invoke(SecurityUtil.java:175) at com.sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer.java:2920) at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4011) at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:203) at com.sun.ejb.containers.EJBObjectInvocationHandlerDelegate.invoke(EJBObjectInvocationHandlerDelegate.java:77) at $Proxy139.connect(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke(ReflectiveTie.java:154) at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:687) at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:227) at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1846) at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:1706) at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:1088) at com.sun.corba.ee.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:223) at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:806) at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.dispatch(CorbaMessageMediatorImpl.java:563) at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.doWork(CorbaMessageMediatorImpl.java:2567) at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:555)

3 Respostas

T

Antes de mais nada use a tag [code] pra identar seus códigos aqui no forum.

Prosseguindo, por que seu bean recebe um EntityManager na construção? Deixe que o servidor de aplicações administre isso.

M

Primeiro desculpe com relação a tag code, não sabia sobre a existência dela.
Resposta, fiz isso simplesmente por que quando criei esse código, a um bom tempo, realizava testes fora do contêiner. Dessa forma não tinha como injetar a dependência pois como dito estaria fora do contêiner, o arquivo de teste fazia a criação do entiymanager através de uma fabrica e ao instanciar um LocationServiceBean ele passava esse bean para ele, o qual estaria referenciando um banco de dados de teste derby. Hoje já estou realizando testes no contêiner openejb, por tanto esse construtor ai é apenas código antigo que não foi devidamente removido. Mas ele pode ser removido tranqüilamente pois não está mais sendo utilizado no meu código em lugar nenhum.
Bom mas creio que não seja esse o problema, de qualquer forma vou testar para ter certeza.

M

Testado, realmente não influencia

Criado 10 de setembro de 2009
Ultima resposta 11 de set. de 2009
Respostas 3
Participantes 2