Problema para capturar exceções do Glassfish

20 respostas
C

Boa tarde,

Estou tendo dificuldades para recuperar uma exceção gerada no servidor de aplicação Glassfish. Vou detalhar o cenário para melhor entendimento.

A aplicação usa EJB3, JPA e o acesso a base é feita através de JDBC resource criado no servidor de aplicação.

Em minhas classes de persistência está definido que o acesso a base de dados, se dará através desta anotação.

@PersistenceContext(unitName = "BANCODEDADOS", type = PersistenceContextType.TRANSACTION)
    protected EntityManager em;

No arquivo persistence.xml tenho um unidade de persistência BANCODEDADOS que aponta para um JDBC Resources configurado no Glassfish, conforme abaixo:

<persistence-unit name="BANCODEDADOS">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>BANCODEDADOS-PGSQL</jta-data-source>
    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
    </properties>
  </persistence-unit>

Enfim, vamos ao problema.

Quando utilizo as classes de persistência para, por exemplo, a remoção de uma entidade que tem outras dependendo dela através da instrução remove do EntityManager, como abaixo:

em.remove(obj);

Não seria o caso de composição, ou seja, não se aplica a remoção em cascata.

Não é disparado exceção alguma, simplesmente a instrução é executada e pronto. Entretanto o objeto não foi removido e se observar no log do Glassfish vai ter uma informação, conforme pilha abaixo.

Essa exceção foi gerada devido a restrição de integridade da base de dados e não foi disparada para o método remove do EntityManager e assim não é possível tratá-la.

Aparentemente quando executa-se o método remove do EntityManager, é consultado a base de dados via Glassfish e esse não repassa a exceção gerada devido ao erro de integridade.

Alguém saberia me informa algo a respeito disso? Se existe alguma configuração no Glassfish, ou algo parecido.

[#|2010-04-06T15:30:13.148-0300|INFO|sun-appserver9.1|javax.enterprise.system.container.ejb|_ThreadID=17;_ThreadName=httpSSLWorkerThread-10080-1;|
javax.ejb.EJBException: Transaction aborted; nested exception is: javax.transaction.RollbackException: Transaction marked for rollback.
javax.transaction.RollbackException: Transaction marked for rollback.
	at com.sun.enterprise.distributedtx.J2EETransaction.commit(J2EETransaction.java:440)
	at com.sun.enterprise.distributedtx.J2EETransactionManagerOpt.commit(J2EETransactionManagerOpt.java:371)
	at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:3792)
	at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:3571)
	at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1354)
	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:117)
	at $Proxy56.removerUsuario(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.com.erp.gestaoacesso.model.facade.interfaces.__UsuarioFacadeRemote_Remote_DynamicStub.removerUsuario(br/com/erp/gestaoacesso/model/facade/interfaces/__UsuarioFacadeRemote_Remote_DynamicStub.java)
	at br.com.erp.gestaoacesso.model.facade.interfaces._UsuarioFacadeRemote_Wrapper.removerUsuario(br/com/erp/gestaoacesso/model/facade/interfaces/_UsuarioFacadeRemote_Wrapper.java)
	at br.com.erp.gestaoacesso.view.presenter.impl.UsuarioPresenter.removerUsuario(UsuarioPresenter.java:42)
	at br.com.erp.gestaoacesso.view.formularios.impl.UsuarioForm.removerUsuario(UsuarioForm.java:78)
	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.el.parser.AstValue.invoke(AstValue.java:187)
	at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
	at org.apache.myfaces.trinidadinternal.taglib.util.MethodExpressionMethodBinding.invoke(MethodExpressionMethodBinding.java:53)
	at org.apache.myfaces.trinidad.component.UIXComponentBase.broadcastToMethodBinding(UIXComponentBase.java:1245)
	at org.apache.myfaces.trinidad.component.UIXCommand.broadcast(UIXCommand.java:183)
	at org.apache.myfaces.trinidad.component.UIXCollection.broadcast(UIXCollection.java:147)
	at org.apache.myfaces.trinidad.component.UIXTable.broadcast(UIXTable.java:271)
	at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:447)
	at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:752)
	at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:97)
	at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251)
	at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:244)
	at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:411)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:317)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
	at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl._doFilterImpl(TrinidadFilterImpl.java:247)
	at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl.doFilter(TrinidadFilterImpl.java:157)
	at org.apache.myfaces.trinidad.webapp.TrinidadFilter.doFilter(TrinidadFilter.java:92)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
	at br.com.erp.gestaocomum.view.util.SecurityFilter.doFilter(SecurityFilter.java:80)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
	at br.com.erp.gestaocomum.view.util.SecurityFilter.doFilter(SecurityFilter.java:80)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
	at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:285)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
	at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:341)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:288)
	at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:271)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:202)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
	at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:206)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
	at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:150)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
	at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
	at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:272)
	at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:637)
	at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:568)
	at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:813)
	at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341)
	at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:263)
	at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:214)
	at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
	at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)
javax.ejb.EJBException: Transaction aborted; nested exception is: javax.transaction.RollbackException: Transaction marked for rollback.
	at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:3798)
	at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:3571)
	at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1354)
	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:117)
	at $Proxy56.removerUsuario(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.com.erp.gestaoacesso.model.facade.interfaces.__UsuarioFacadeRemote_Remote_DynamicStub.removerUsuario(br/com/erp/gestaoacesso/model/facade/interfaces/__UsuarioFacadeRemote_Remote_DynamicStub.java)
	at br.com.erp.gestaoacesso.model.facade.interfaces._UsuarioFacadeRemote_Wrapper.removerUsuario(br/com/erp/gestaoacesso/model/facade/interfaces/_UsuarioFacadeRemote_Wrapper.java)
	at br.com.erp.gestaoacesso.view.presenter.impl.UsuarioPresenter.removerUsuario(UsuarioPresenter.java:42)
	at br.com.erp.gestaoacesso.view.formularios.impl.UsuarioForm.removerUsuario(UsuarioForm.java:78)
	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.el.parser.AstValue.invoke(AstValue.java:187)
	at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
	at org.apache.myfaces.trinidadinternal.taglib.util.MethodExpressionMethodBinding.invoke(MethodExpressionMethodBinding.java:53)
	at org.apache.myfaces.trinidad.component.UIXComponentBase.broadcastToMethodBinding(UIXComponentBase.java:1245)
	at org.apache.myfaces.trinidad.component.UIXCommand.broadcast(UIXCommand.java:183)
	at org.apache.myfaces.trinidad.component.UIXCollection.broadcast(UIXCollection.java:147)
	at org.apache.myfaces.trinidad.component.UIXTable.broadcast(UIXTable.java:271)
	at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:447)
	at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:752)
	at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:97)
	at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251)
	at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:244)
	at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:411)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:317)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
	at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl._doFilterImpl(TrinidadFilterImpl.java:247)
	at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl.doFilter(TrinidadFilterImpl.java:157)
	at org.apache.myfaces.trinidad.webapp.TrinidadFilter.doFilter(TrinidadFilter.java:92)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
	at br.com.erp.gestaocomum.view.util.SecurityFilter.doFilter(SecurityFilter.java:80)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
	at br.com.erp.gestaocomum.view.util.SecurityFilter.doFilter(SecurityFilter.java:80)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
	at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:285)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
	at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:341)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:288)
	at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:271)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:202)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
	at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:206)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
	at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:150)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
	at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
	at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:272)
	at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:637)
	at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:568)
	at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:813)
	at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341)
	at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:263)
	at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:214)
	at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
	at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)

@braços

20 Respostas

renanreismartins

acho que no seu stacktrace tem mais coisas… poste depois caso isto nao resolver:

tente tratar sua exception por exemplo no codigo onde vc chama o remove faça:

try {
   em.remove(obj);
} catch () {
system.out.println("erro ao remover");
system.out.println(e);
}

pelo que entendi isso resolve…

abrasssssssss

G

Quando você está em um ambiente J2EE e seu EJB lança uma exception que não é uma RMIException o container tende a fazer um wrapper dessa exception em uma RMIException. Talvez por isso você não consiga ver a exception real. Isso acontece em qualquer appserver, seja um Glassfish ou OC4J ou outro qualquer.

Porém cabe lembrar que a exception possui um método para saber a causa: Exception.getCause(). Com esse método você consegue saber o erro que aconteceu.

C

Então Renan… Isso eu já faço. Veja abaixo o método:

public void removerEntidade(Object id, Class clazz) throws ERPException {
        try {
            Object obj = carregarEntidade(id, clazz);
            em.remove(obj);
            System.out.println("DEBUGANDO ..... ");
        } catch (IllegalStateException isex) {
            throw new ERPException(MessageBundle.EXCEPTION_ILLEGAL_STATE, isex);
        } catch (IllegalArgumentException iaex) {
            throw new ERPException(MessageBundle.EXCEPTION_ILLEGAL_ARGUMENT, iaex);
        } catch (TransactionRequiredException trex) {
            throw new ERPException(MessageBundle.EXCEPTION_TRANSACTION_REQUIRED, trex);
        } catch(Exception ex) {
            throw new ERPException(MessageBundle.EXCEPTION_GENERIC, ex);
        }
    }

A mensagem "DEBUGANDO … " é impressa no log do Glassfish normalmente. Isso indica que não é disparada nenhuma exceção. E logo após a mensagem "DEBUGANDO … " no log do Glassfish vem a pilha conforme postei anteriormente, e detalhe ela está completa.

Por isso disse que para a aplicação, ocorreu tudo bem na remoção, mas como o Glassfish gerencia a conexão com a base de dados, ele recebe o erro do banco de dados, grava essa pilha no log, mas não repassa para aplicação.

@braços

C

garcia-jj:
Quando você está em um ambiente J2EE e seu EJB lança uma exception que não é uma RMIException o container tende a fazer um wrapper dessa exception em uma RMIException. Talvez por isso você não consiga ver a exception real. Isso acontece em qualquer appserver, seja um Glassfish ou OC4J ou outro qualquer.

Porém cabe lembrar que a exception possui um método para saber a causa: Exception.getCause(). Com esse método você consegue saber o erro que aconteceu.

Garcia,

O problema não é que não consigo ver a exception real. O problema é que não é gerada uma exception, conforme postei em resposta ao Renan. O método finaliza sem gerar exceção alguma, mas o objeto não é removido e no log do Glassfish aparece a pilha do primeiro post.

@braços

C

Pessoal,

Procurando no fórum achei um post do Frederico. Ele teve o mesmo problema com o servidor de aplicação JBOSS. Vejam no link abaixo:

http://www.guj.com.br/posts/list/98766.java#531953

@braços

C

Pessoal,

Outro post do Townray que pelo que percebi também encontrou o mesmo problema.

http://www.guj.com.br/posts/list/147420.java

@braços

C

E aí galera… novidades?

@braços

renanreismartins

as transacoes do seu SessionBean sao gerenciadas pelo container ?

abrasss

C

renanreismartins:
as transacoes do seu SessionBean sao gerenciadas pelo container ?

abrasss

Sim… São gerenciadas pelo container mesmo.

@braços

renanreismartins

nao li a esp. entao posso estar errado, mas até onde entendo se sua transacao é gerenciada pelo container ela é comitada no fim do metodo do ejb, ou seja, durante o metodo ela ainda nao ocorreu.

lendo a documentacao da RollbackException vc encontra:
Thrown by the persistence provider when the EntityTransaction.commit() fails.

ou seja essa exceçao pode acontecer na chamada do commit, este que por sua vez é realizado pelo container.

entao o certo seria vc tratar na chamada do ejb

try {
     meuEJB.metodoQueRemove(usuario);
} catch(EJBException e) {
 // mostra msg pro user
}

espero que resolva…

ps: onde vc viu que é violaçao de integridade do banco?

abrassssssss

C

Então Renan,

Não entendi! Como assim tratar no meu EJB? Esse método está anotado como EJB. Veja abaixo:

Eu sei que é restrição pq justamente a entidade que estou tentando remover tem dependências e gera erro, e aumentando o nível de log do Glassfish ele acaba mostrando o erro.

public class GenericEAO implements IGenericEAO {
   
    @PersistenceContext(unitName = "DATASOURCE", type = PersistenceContextType.TRANSACTION)
    protected EntityManager em;

    public Object carregarEntidade(Object id, Class clazz) throws ERPException {
        Object obj = null;
        try {
            obj = em.find(clazz, id);
        } catch (IllegalStateException isex) {
            throw new ERPException(MessageBundle.EXCEPTION_ILLEGAL_STATE, isex);
        } catch (IllegalArgumentException iaex) {
            throw new ERPException(MessageBundle.EXCEPTION_ILLEGAL_ARGUMENT, iaex);
        } catch(Exception ex) {
            throw new ERPException(MessageBundle.EXCEPTION_GENERIC, ex);
        }
        return obj;
    }

    public void removerEntidade(Object id, Class clazz) throws ERPException {
        try {
            Object obj = carregarEntidade(id, clazz);
            em.remove(obj);
        } catch (IllegalStateException isex) {
            throw new ERPException(MessageBundle.EXCEPTION_ILLEGAL_STATE, isex);
        } catch (IllegalArgumentException iaex) {
            throw new ERPException(MessageBundle.EXCEPTION_ILLEGAL_ARGUMENT, iaex);
        } catch (TransactionRequiredException trex) {
            throw new ERPException(MessageBundle.EXCEPTION_TRANSACTION_REQUIRED, trex);
        } catch(Exception ex) {
            throw new ERPException(MessageBundle.EXCEPTION_GENERIC, ex);
        }
    }

}


@Stateless(name="UsuarioEAO", mappedName="UsuarioEAO")
public class UsuarioEAO extends GenericEAO implements IUsuarioEAO {

..........
.......... 

}

@braços

renanreismartins

nao é tratar no seu ejb, mas sim onde vc chama o ejb…

é fazer o tratamento onde vc faz chamadas ao metodo ejb…

entendeu ?

abrasssss

C

renanreismartins:
nao é tratar no seu ejb, mas sim onde vc chama o ejb…

é fazer o tratamento onde vc faz chamadas ao metodo ejb…

entendeu ?

abrasssss

Renan,

Mesmo assim não gerou nada de exceção.

@braços

G

Estou pensando em como te ajudar, mas não consigo ver o problema. A principio quando você usa um EJB (tanto faz remote ou local, stateless ou stateful) e dá um erro, ele te retorna esse erro enjaulado em uma RMIException. Note que sempre que o método EJB acaba a execução a transação é verificada e é lançado todos os erros.

Ou seja, se você está em um ManagedBean e chamou um método EJB que lançou algum erro ele irá te estourar de qualquer forma. Não há como ser diferente, pois o flush é feito logo que acaba a execução do método EJB.

Você não está mascarando a exception? Algo como:

try { meuEJB.metodo(); } catch(Exception e) { e.printStackTrace(); }

Note que assim você imprime no log porém nada é exibido na tela.

Você pode nos deixar os trechos dos códigos envolvidos? Seu EJB, ManagedBean…

C

Boa noite garcia-jj,

Então… Compreendo bem o ambiente J2EE, agradeço o esforço em em ajudar, mas como disse nos posts anteriores, realmente não está sendo lançada exceção alguma. Não costumo mascarar exceções, tenho como boa prática o tratamento das mesmas, como você pode ver nos métodos que postei anteriormente.

Veja abaixo como estão as classes envolvidas. Eu tenho uma classe genérica com os métodos CRUD, e uma classe UsuarioEAO que estende essa genérica e implementa outros métodos relacionados à persistência para classe de usuário.

Nesta classe genérica a anotação @PersistenceContext injeta o EntityManager com base no jdbc resources configurado no Glassfish e a transação é controlada pelo contâiner.

Quando o método removerEntidade é invocado por uma classe de serviço UsuarioService, que utiliza o EJB UsuarioEAO injetado através da anotação @EJB, a remoção não dispara nenhuma exceção. Veja que na classe de serviço é declarado um throws no método. A exceção é tratada na camada de apresentação, porque vai ser obrigada a tratar ou repassar, caso contrário vai para a saída padrão.

Observe que tem uma classe na camada de apresentação chamada UsuarioForm, que utiliza o serviço de UsuarioService que por sua vez utiliza o EJB UsuarioEAO que faz a remoção com EntityManager do JPA via transação gerenciada pelo contâiner.

Após a execução da remoção não é gerada exceção nenhuma. E a prova disso é que a mensagem “DEBUGANDO…” é impressa normalmente, como vc pode ver no método removerEntidade da classe GenericEAO.

Enfim, eu resolvi o problema controlando a transação direto no EJB e funciona normalmente, ou seja, ele dispara a exceção e ela chega na camada de apresentação corretamente.

O que eu queria entender é o porque a exceção gerada na transação gerenciada pelo contânier não é reportada no EJB.

public class GenericEAO implements IGenericEAO {   
     
    @PersistenceContext(unitName = "DATASOURCE", type = PersistenceContextType.TRANSACTION)   
    protected EntityManager em;   
  
    public Object carregarEntidade(Object id, Class clazz) throws ERPException {   
        Object obj = null;   
        try {   
            obj = em.find(clazz, id);   
        } catch (IllegalStateException isex) {   
            throw new ERPException(MessageBundle.EXCEPTION_ILLEGAL_STATE, isex);   
        } catch (IllegalArgumentException iaex) {   
            throw new ERPException(MessageBundle.EXCEPTION_ILLEGAL_ARGUMENT, iaex);   
        } catch(Exception ex) {   
            throw new ERPException(MessageBundle.EXCEPTION_GENERIC, ex);   
        }   
        return obj;   
    }   
  
    public void removerEntidade(Object id, Class clazz) throws ERPException {   
        try {   
            Object obj = carregarEntidade(id, clazz);   
            em.remove(obj);   
            System.out.println("DEBUGANDO.....");
        } catch (IllegalStateException isex) {   
            throw new ERPException(MessageBundle.EXCEPTION_ILLEGAL_STATE, isex);   
        } catch (IllegalArgumentException iaex) {   
            throw new ERPException(MessageBundle.EXCEPTION_ILLEGAL_ARGUMENT, iaex);   
        } catch (TransactionRequiredException trex) {   
            throw new ERPException(MessageBundle.EXCEPTION_TRANSACTION_REQUIRED, trex);   
        } catch(Exception ex) {   
            throw new ERPException(MessageBundle.EXCEPTION_GENERIC, ex);   
        }   
    }   
  
}   
  
  
@Stateless(name="UsuarioEAO", mappedName="UsuarioEAO")   
public class UsuarioEAO extends GenericEAO implements IUsuarioEAO {   
  
..........   
..........   
  
}


@Stateless(name="UsuarioService", mappedName="UsuarioService")
public class UsuarioService implements UsuarioServiceRemote, UsuarioServiceLocal {
    @EJB
    private IUsuarioEAO usuarioEAO;

    public void removerUsuario(Long idUsuario)  throws ERPException {
        usuarioEAO.removerEntidade(idUsuario, Usuario.class);
    }

}

public class UsuarioForm extends BaseForm implements IUsuarioForm {

    .....

    public void removerUsuario(ActionEvent actionEvent) {
        try {
            this.editUsuario = (Usuario)this.tableUsuarios.getSelectedRowData();
            if(this.editUsuario != null) {
                this.usuarioService.removerUsuario(this.editUsuario.getIdUsuario());            
                doPartialTrigger(this.tableUsuarios);
            } else {
                throw new ERPException(MessageBundle.ACESSO_USUARIO_NAO_SELECIONADO);
            }
        } catch (Exception ex) {
            super.addErrorMessage(ex);
        }
    }

    .....

}

Espero que tenha ficado claro agora.

@braços

G

Agora entendi. Eu já tive esse problema.

Na linha 23, onde você chama em.remove(obj) adicione um em.flush(). Segue um exemplo de um método meu. Isso faz com que tudo seja executado "right now". Porém o flush não chega a fazer commit, assim você ainda consegue seguir usando o JTA em CTM normalmente.

public T remove(T entity) {
    entity = getEntityManager().remove(entity);
    getEntityManager().flush(); // execute now

    return entity;
}
renanreismartins

garcia-jj mas isso nao faz com que se perca aquela vantagem do container enviar os dados quando for “mais vantajoso” ?

abrassssssss

Paulo_Silveira

oi pessoal

em algum lugar a transacao esta sendo marcada para dar rollback. existem duas maneiras disso acontecer: pelo sessionContext.setRollbackOnly ou lancando uma exception unchecked (system exception na terminologia do ejb, que tambem pode ser uma checkedexception caso voce tenha a configurado assim).

esses montes de catches e throws podem estar enganando a gente. existe algum catch que voce nao esta fazendo o rethrow? vi na stacktrace que voce tem um filtro, pode postar o filtro pra gente?

C

Paulo,

Se você está se referindo à este filtro br.com.erp.gestaocomum.view.util.SecurityFilter, ele serve para controle de acesso na camada web, ou seja, não interfere na questão das exceções.

O grande problema está neste método conforme posts anteriores.

public void removerEntidade(Object id, Class clazz) throws ERPException {     
        try {     
            Object obj = carregarEntidade(id, clazz);     
            em.remove(obj);     
            System.out.println("DEBUGANDO.....");   
        } catch (IllegalStateException isex) {     
            throw new ERPException(MessageBundle.EXCEPTION_ILLEGAL_STATE, isex);     
        } catch (IllegalArgumentException iaex) {     
            throw new ERPException(MessageBundle.EXCEPTION_ILLEGAL_ARGUMENT, iaex);     
        } catch (TransactionRequiredException trex) {     
            throw new ERPException(MessageBundle.EXCEPTION_TRANSACTION_REQUIRED, trex);     
        } catch(Exception ex) {     
            throw new ERPException(MessageBundle.EXCEPTION_GENERIC, ex);     
        }     
    }

Observe que tem a instrução System.out.println(“DEBUGANDO…”). Esta instrução é executado e isso indica que não houve qualquer exceção na execução deste método, mas no log do Glassfish aparece aquela pilha que postei inicialmente.

Veja que neste método são tratadas as exceções que podem ocorrer neste método remove e ainda para garantir que não escape outra inesperada, foi colocado um catch Exception. Assim sendo qualquer exceção especializada de Exception, inclusive RuntimeException que herda Exception será capturada e tratada, ou seja, checked e uncheckedexception serão capturadas e tratadas.

E se vc observar no meu último post as exceções ERPException disparadas lá em GenericEAO são deixadas para o UsuarioForm exibir para o usuário através de um componente visual através de super.addErrorMessage(ex).

Assim sendo, não tem como qualquer exceção gerada lá no GenericEAO através do EntityManager, não chegar no formulário WEB.

Consegui provar isso, porque deixando a mesma estrutura somente alterei no GenericEAO para ao invés de deixar o controle de transação via contâiner, controlo no EJB.

persistence.xml

  <persistence-unit name="DATASOURCE" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <properties>
      <property name="hibernate.hbm2ddl.auto" value="none"/>
      <property name="hibernate.connection.username" value="postgres"/>
      <property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
      <property name="hibernate.connection.password" value="SENHADABASE"/>
      <property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/BANCO"/>
      <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
      <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
    </properties>
  </persistence-unit>

public class GenericEAO implements IGenericEAO  {

    private EntityManagerFactory emf = Persistence.createEntityManagerFactory("DATASOURCE");

    public EntityManager getEntityManager() {
        return this.emf.createEntityManager();
    }

    public void removerEntidade(Object id, Class clazz) throws ERPException {
        EntityManager em = this.getEntityManager();
        EntityTransaction et = null;
        try {
            et = em.getTransaction();
            et.begin();
            Object obj = em.find(clazz, id);
            em.remove(obj);
            et.commit();
        } catch (IllegalStateException isex) {
            throw new ERPException(MessageBundle.EXCEPTION_ILLEGAL_STATE, isex);
        } catch (IllegalArgumentException iaex) {
            throw new ERPException(MessageBundle.EXCEPTION_ILLEGAL_ARGUMENT, iaex);
        } catch (TransactionRequiredException trex) {
            throw new ERPException(MessageBundle.EXCEPTION_TRANSACTION_REQUIRED, trex);
        } catch(Exception ex) {
            throw new ERPException(MessageBundle.EXCEPTION_GENERIC, ex);
        } finally {
            if (et != null && et.isActive()) {
                et.rollback();
            }
            if (em != null && em.isOpen()) {
                em.close();
            }
        }
    }
}

Desta maneira a exceção chega normalmente no formulário WEB.

@braços

F

Você achou alguma solução?

Criado 6 de abril de 2010
Ultima resposta 14 de jun. de 2011
Respostas 20
Participantes 5