[Resolvido] Não consigo pegar nenhuma exception do Eclipse Link, utilizando JTA

Eu não consigo capturar nenhuma exceção dessa maneira, alguém sabe o que pode estar acontecendo? Ele gera erro na view e no console, mas não consigo capturar a exception… segue o código:

@TransactionManagement(TransactionManagementType.CONTAINER)
public abstract class AbstractFacade<T> {
    private Class<T> entityClass;

    public AbstractFacade(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    protected abstract EntityManager getEntityManager();
    
    public void create(T entity) {
        try{
        getEntityManager().persist(entity);
        } catch(Exception e){
            //OBVIO QUE ISSO NÃO VAI FICAR ASSIM, É SÓ ILUSTRATIVO!
            System.out.println("PASSOU");
        }
    }
    

}

Segue o erro no console:

Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'a' for key 'nome'
Error Code: 1062
Call: INSERT INTO PERSONAGEM (acoesCombate, altura, baseAtaque, car, clasLabel, con, creditos, des, forc, fort, idiomas, iniciativa, inte, nivel, nome, percepcao, peso, pontosDestino, pontosFroca, pontosLadoNegro, pontosVida, refl, sab, sexo, usandoArmadura, vont, ESPECIE_ID) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
	bind => [27 parameters bound]
Query: InsertObjectQuery(model.personagem[ id=null ])
	at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:324)
	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:840)
	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:906)
	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:592)
	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:535)
	at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1717)
	at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:253)
	at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:207)
	at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:193)
	at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.insertObject(DatasourceCallQueryMechanism.java:342)
	at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:162)
	at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:177)
	at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:472)
	at org.eclipse.persistence.queries.InsertObjectQuery.executeCommit(InsertObjectQuery.java:80)
	at org.eclipse.persistence.queries.InsertObjectQuery.executeCommitWithChangeSet(InsertObjectQuery.java:90)
	at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:287)
	at org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:58)
	at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:844)
	at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:743)
	at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108)
	at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2871)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1516)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1498)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1449)
	at org.eclipse.persistence.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet(CommitManager.java:224)
	at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsForClassWithChangeSet(CommitManager.java:191)
	at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:136)
	at org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:3799)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1415)
	at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:636)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1505)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.issueSQLbeforeCompletion(UnitOfWorkImpl.java:3143)
	at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.issueSQLbeforeCompletion(RepeatableWriteUnitOfWork.java:346)
	at org.eclipse.persistence.transaction.AbstractSynchronizationListener.beforeCompletion(AbstractSynchronizationListener.java:157)
	at org.eclipse.persistence.transaction.JTASynchronizationListener.beforeCompletion(JTASynchronizationListener.java:68)
	at com.sun.enterprise.transaction.JavaEETransactionImpl.commit(JavaEETransactionImpl.java:435)
	at com.sun.enterprise.transaction.JavaEETransactionManagerSimplified.commit(JavaEETransactionManagerSimplified.java:855)
	at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5136)
	at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4901)
	at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2045)
	at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1994)
	at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:222)
	at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:89)
	at $Proxy261.create(Unknown Source)
	at dao.__EJB31_Generated__PersonagemFacade__Intf____Bean__.create(Unknown Source)
	at Controller.PersonagemController.criar(PersonagemController.java:249)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at com.sun.el.parser.AstValue.invoke(AstValue.java:254)
	at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:302)
	at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:39)
	at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
	at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
	at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
	at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
	at javax.faces.component.UICommand.broadcast(UICommand.java:315)
	at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
	at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
	at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
	at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
	at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
	at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
	at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
	at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
	at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
	at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
	at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
	at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
	at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
	at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
	at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
	at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
	at java.lang.Thread.run(Thread.java:722)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'a' for key 'nome'
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
	at com.mysql.jdbc.Util.getInstance(Util.java:384)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1041)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3566)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3498)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2113)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2568)
	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2113)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2409)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2327)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2312)
	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:831)
	... 92 more

Ahh é obvio que eu tenho uma classe que estende essa abstrata:

[code]@Stateless
public class PersonagemFacade extends AbstractFacade {

@PersistenceContext(unitName = "StarWarsPU")
private EntityManager em;

@Override
protected EntityManager getEntityManager() {
    return em;
}

public PersonagemFacade() {
    super(Personagem.class);
}

}[/code]

Está tudo perfeito, o único problema é que não consigo capturar exception.

MySQLIntegrityConstraintViolationException: Duplicate entry ‘a’ for key ‘nome’

Creio que o erro é por que você tentou salvar um nome repetido.

Não tenha medo de ler o stacktrace. :wink:

jakefrog

Ei amigo, eu li o StackTrace… Você entendeu errado a minha duvida. Eu sei que eu lancei uma MySQLIntegrityConstraintViolationException, exatamente porque eu QUERIA lançar uma. O problema é que eu não consigo de maneira nenhuma capturar essa exception com um Try/Catch para trata-la e exibir uma mensagem bonitinha para o usuário, sacou? Desculpa se não deixei claro na primeira vez x/.

[quote=diegosammet]jakefrog

Ei amigo, eu li o StackTrace… Você entendeu errado a minha duvida. Eu sei que eu lancei uma MySQLIntegrityConstraintViolationException, exatamente porque eu QUERIA lançar uma. O problema é que eu não consigo de maneira nenhuma capturar essa exception com um Try/Catch para trata-la e exibir uma mensagem bonitinha para o usuário, sacou? Desculpa se não deixei claro na primeira vez x/.[/quote]AAAA ta. Desculpa, li errado. MAhuauhaa
Tente fazer o try/catch em cima do MySQLIntegrityConstraintViolationException ou do DatabaseException

Ja fiz, foram minhas primeiras tentativas. Acho que o problema é com o EclipseLink, pois tenho outra aplicação funcionando da mesma maneira (JPA + JTA) mas utilizando o Hibernate como implementação e ele captura esse tipo de exception na boa… O problema é que eu não tava afim de mudar de implementação (Sem saco pra colocar os Jar do hibernate no servidor)…

Inclusive:

[code]
@TransactionManagement(TransactionManagementType.CONTAINER)
public abstract class AbstractFacade implements IDao {
private Class entityClass;
protected Validador validador = new Validador();

public AbstractFacade(Class<T> entityClass) {
    this.entityClass = entityClass;
}

protected abstract EntityManager getEntityManager();

public void create(T entity) throws NuloException, UniqueConstraintException, PersistenceException{

//
if(validador.validaNulo(entity)){
try{
getEntityManager().persist(entity);
}
catch(PersistenceException e){
if (e.getCause().getClass().equals(ConstraintViolationException.class)){
throw new UniqueConstraintException(e.getCause());
}
}

    }
    
}[/code]

Esse código é o que está na minha outra aplicação, e funciona… A diferença é que ela utiliza o Hibernate e não o EclipseLink… Talvez exista alguma configuração… sei la.

É cara, aí não sei.

Tenta perguntar no forum deles. isso é coisa específica de cada implementação. [=

Segundo esta mensagem:

http://stackoverflow.com/questions/7382169/how-do-i-catch-the-constraint-violation-exception-from-eclipselink

isso é um bug do eclipselink e você tem que capturar RollbackException ao invés de PersistenceException…
tem que testar pra ver

Sem sucesso…

Funcionou…

getEntityManager().flush();

Logo apos o .persist();. Não sei bem o motivo, o que eu ACHO que seja é que o container só fazia a inserção quando commitava a transação e PROVAVELMENTE ele encapsulava a exception e tratava ele mesmo… Desse modo está funcionando perfeitamente, mas se alguém souber o motivo desse comportamento, seria interessante saber…

Coloca no comentário: “Não altere essa linha”

:slight_smile:

[quote=rogeriopaguilar]Coloca no comentário: “Não altere essa linha”

:slight_smile:
[/quote]

AHuaHauiH teria que colocar mesmo… Mas é um projeto particular e que provavelmente só eu vou usar… HAUIHIUahAIUHA

Brincadeiras à parte, é o que você disse mesmo, se você não chama o flush ele só vai fazer isso no final da transação.

Alguém já descobriu o segredo? Porque realmente quando coloco o flush() depois do persist() ele consegue lançar a exceção esperada, isso usando eclipselink, só que além disso surge outra dúvida. Séra que deixando assim não vai influenciar na performance do sistema? Pois pra quem usa um DAO genérico e insere vários registros de uma só vez por exemplo, ter que forçar a inserção dos dados (dar flush()) a cada inserção vai reduzir drasticamente o desempenho.

E aí? Alguém conseguiu resolver isso ou vamos ter que usar hibernate mesmo? :slight_smile:

[quote=Vin?ius Abreu de Fran?]Alguém já descobriu o segredo? Porque realmente quando coloco o flush() depois do persist() ele consegue lançar a exceção esperada, isso usando eclipselink, só que além disso surge outra dúvida. Séra que deixando assim não vai influenciar na performance do sistema? Pois pra quem usa um DAO genérico e insere vários registros de uma só vez por exemplo, ter que forçar a inserção dos dados (dar flush()) a cada inserção vai reduzir drasticamente o desempenho.

E aí? Alguém conseguiu resolver isso ou vamos ter que usar hibernate mesmo? :slight_smile: [/quote]

Nao conheco o eclipse link, entao vou palpitar. Se vc colocar esse mesmo try catch na chamada do metodo ao inves de dentro dele nao resolve o problema?

A excecao so sera lancada quando bater no banco e ele so fara isso no momento do commit, entao voce tem que por o tratamento da excecao no commit. Se a transacao eh controlada por algum container ponha o try catch no metodo anotado com @Transaction.