Recuperar exception a partir do HibernateTransactionInterceptor
10 respostas
diguix
O que está acontecendo pessoal é o seguinte.
Estou usando o HibernateTransactionInterceptor para gerenciar as transações do hibernate no Vraptor,
porém quando acontece uma exception(ie. ConstraintViolationException) não consigo recupera-la para tratar na camada de cima.
Gostaria de saber se tem alguma forma de fazer isto, ou algum workaround
Você está usando o hibernate/jpa controlado manualmente ou pelo Vraptor?
Uma coisa que você pode fazer, que fiz algo semelhente em um componente que faz um exception-handler, é verificar se é uma exception do bean validator e tratá-la de forma diferente. Não sei bem o motivo, mas as exceptions do bean validator são um pouco diferentes.
Então cara estou usando o hibernate controlado pelo HibernateCustonProvider.
O problema é que não sei onde implementar essa verificação?
editado: Meu problema é que como estou usando o customprovider ele não me gera exception e passa direto so exibindo no log.
Você criou um interceptor específico?
gostei muito da dica,
obrigado e Abraços;
Lucas_Cavalcanti
cria um interceptor:
@InterceptspublicclassConstraintViolationInterceptionimplementsInterceptor{accepts(method){returntrue;}intercept(stack,method,instance){try{stack.next(method,instance);}catch(exception){// o código que o garcia postou}}}
Meu interceptor não está pegando a exception, dei uma olhada no código do HibernateCustomProvider e só tem try e finally.
Lucas, você sabe qual componente do Vrpator está entubando esta exceção?
ou eu to perdido demais
Abraços.
Lucas_Cavalcanti
dá um try…catch em InterceptorException e usa o e.getCause pra saber qual exceção foi
diguix
pessoal o seguinte consegui fazendo uma adaptação, tive que reescrever o HibernateTransactionInterceptor,
inserindo o bloco do catch e incluindo o result para responder as minhas necessidades.
@InterceptspublicclassHibernateTransactionInterceptorimplementsInterceptor{privatefinalSessionsession;privatefinalResultresult;publicHibernateTransactionInterceptor(Sessionsession,Resultresult){this.session=session;this.result=result;}publicvoidintercept(InterceptorStackstack,ResourceMethodmethod,Objectinstance)throwsInterceptionException{Transactiontransaction=null;try{transaction=session.beginTransaction();stack.next(method,instance);transaction.commit();}catch(Exceptione){Throwablecause=ExceptionUtils.getCause(e);if(causeinstanceofBatchUpdateException){this.result.use(Results.http()).setStatusCode(409);}}finally{if(transaction!=null&&transaction.isActive()){transaction.rollback();}}}publicbooleanaccepts(ResourceMethodmethod){returntrue;// Will intercept all requests}}
e Escrevi um CustomProvider para implementar o meu HibernateTransactionInterceptor.
o que vocês acham? resolveu meu problema.
Abraços.
Lucas_Cavalcanti
só toma cuidado que vc tá engolindo a exceção… faça o seguinte, dentro do catch:
a exception já é logada automaticamente, acho que pelo próprio transaction.commit(); quando ele quebra.
mas só por garantia vou logar também.
G
garcia-jj
O ideal é sempre deixar para fazer o log em sua camada mais externa, senão quando der uma exception você terá muitos stacktrace para um mesmo erro, dificultando a visualização dos logs. A menos, claro, que você trate essa exception; nesse caso é melhor fazer o logging dela e depois tratar. (Como é o caso dele “setar o status”)