Rollback hibernate, ManagedBean, OpensessionView e persistencia automática

Galera…

Tenho um campo na minha view que valido no managedbean. Acontece que se a validação não for satisfatória eu lanço uma exceção e nada que foi alterado no formulário é pra ser salvo no banco.

Porém, não é assim que está sendo o comportamento. Todas as alterações que foram feitas no formulário foram alteradas no banco.

Como eu faço pra evitar que o hibernate persista esse objeto quando essa exceção é lançada.

Eu uso o Opensseionview então o início da transação e o fim dela está delimitada nesta classe.

O que vcs sugerem ?

[quote=efcjunior]Galera…

Tenho um campo na minha view que valido no managedbean. Acontece que se a validação não for satisfatória eu lanço uma exceção e nada que foi alterado no formulário é pra ser salvo no banco.

Porém, não é assim que está sendo o comportamento. Todas as alterações que foram feitas no formulário foram alteradas no banco.

Como eu faço pra evitar que o hibernate persista esse objeto quando essa exceção é lançada.

Eu uso o Opensseionview então o início da transação e o fim dela está delimitada nesta classe.

O que vcs sugerem ?[/quote]Até onde eu sei, open session in view tem o controle da transação em um filter normalmente.

Você está fazendo o rollback na unha em alguma parte do código?

Aí está o opensession view. Não tenho em nenhum lugar mais um controle de transação e de sessão.

package sigpr.web.view.filter;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.SessionFactory;
import org.hibernate.StaleObjectStateException;
import sigpr.modelo.conexao.HibernateUtil;

public class ConexaoHibernateFilter implements Filter {

   private static Log log = LogFactory.getLog(ConexaoHibernateFilter.class);
   
   private SessionFactory sf;

   public void doFilter(ServletRequest request,
                        ServletResponse response,
                        FilterChain chain)
           throws IOException, ServletException {

       try {
           log.debug("Starting a database transaction");      
           
           sf.getCurrentSession().beginTransaction();
           
           // Call the next filter (continue request processing)
           chain.doFilter(request, response);

           // Commit and cleanup
           log.debug("Committing the database transaction");
           sf.getCurrentSession().getTransaction().commit();

       } catch (StaleObjectStateException staleEx) {
           log.error("This interceptor does not implement optimistic concurrency control!");
           log.error("Your application will not work until you add compensation actions!");
           // Rollback, close everything, possibly compensate for any permanent changes
           // during the conversation, and finally restart business conversation. Maybe
           // give the user of the application a chance to merge some of his work with
           // fresh data... what you do here depends on your applications design.
           throw staleEx;
       } catch (Throwable ex) {
           // Rollback only
           ex.printStackTrace();
           try {
               if (sf.getCurrentSession().getTransaction().isActive()) {
                   log.debug("Trying to rollback database transaction after exception");
                   sf.getCurrentSession().getTransaction().rollback();
               }
           } catch (Throwable rbEx) {
               log.error("Could not rollback transaction after exception!", rbEx);
           }

           // Let others handle it... maybe another interceptor for exceptions?
           throw new ServletException(ex);
       }
   }

   public void init(FilterConfig filterConfig) throws ServletException {
       log.debug("Initializing filter...");
       log.debug("Obtaining SessionFactory from static HibernateUtil singleton");
       sf = HibernateUtil.getSessionFactory();
   }

   public void destroy() {}


}

Hibernate é uma bomba e uma carroça desenfreada…

Uma solução que precisa de várias soluções ou gambiarras não pode ser considerada uma solução.

Simplesmente não quero que ele salva automático ? E agora ? Tenho que fazer toda uma gambiarra pra burlar isso.

To me enchendo disso.

Calma cara. q revolta… MAuhahuauh

Vc tem que fazer o rollback uai. C quem está usando errado. :stuck_out_tongue:

É algo tipo assim:[code]Transaction t=null;
try {
t = session.beginTransaction();
session.saveOrUpdate(o);
t.commit();
} catch (HibernateException ex) {
logger.error(ex);
ex.printStackTrace();
if (null!=t) {
t.rollback();
}
} finally{
if (null!=t) {
t.rollback();
}

session.flush(); // session seria sua sessão. [=
}[/code]Aqui tem um exemplo: http://www.java2s.com/Code/Java/Hibernate/TransactionRollbackIllustration.htm

kkkk…Ow mas, o problema é que exceção está sendo lançada na validação do campo no managedbean.

Meu problema que eu constatei que qualquer erro que é lançado no managedBean a transação é commitada no open session view normalmente porque ele não captura e consequentemente não faz rollback.

   public void alterarFuncao(){
      try {
         validaCampoData();
         salvaHistoricoFuncaoInativa();
         EmpregadoRN empregadoRN = new EmpregadoRN();
         empregadoRN.salvar(this.empregado);
         salvaHistoricoFuncaoAtiva();
         GlobalFacesMessage.addGlobalMessageInfo(AppMsgs.INFO_ADD_UPDATE_REG);
      }
      catch (Exception e) {         
         GlobalFacesMessage.addGlobalMessageError(AppMsgs.ERRO_ADD_UPDATE_REG);
         e.printStackTrace();        
      }
   }

Tentou colocar o rollback lah? Mano, não esquece que vc tem que fechar tudo que vc abre. Sessão, transação e tudo mais.

Mas se a action no managedbean não lançar a exceção, como que o filter vai saber que a exceção aconteceu? o problema não é esse?

[quote=ezmarques]Mas se a action no managedbean não lançar a exceção, como que o filter vai saber que a exceção aconteceu? o problema não é esse?[/quote]Mano, você testou?

Pelo que estou entendendo mesmo que no meu open session view eu tenha iniciado transação e sessão e fechado transação e sessão eu preciso colocar tb colocar essas instruções na DAO ?

Pelo que estou entendendo mesmo que no meu open session view eu tenha iniciado transação e sessão e fechado transação e sessão eu preciso colocar tb colocar essas instruções na DAO ?[/quote]O aconselhável é fechar onde você abriu. [=

Olá pessoal,

Sei que o tópico é um pouco antigo, mas estou com o mesmo problema.

Se o ManagedBean lança uma exceção o javax.servlet.Filter reponsável por controlar a transação não reconhece essa exceção.

O resultado é que o bloco catch do Filter nunca é executado consequentemente nunca será dado rollback.

Será que alguém já conseguiu encontrar solução para esse problema ?

Abraços

[quote]Hibernate é uma bomba e uma carroça desenfreada…

Uma solução que precisa de várias soluções ou gambiarras não pode ser considerada uma solução.

Simplesmente não quero que ele salva automático ? E agora ? Tenho que fazer toda uma gambiarra pra burlar isso.

To me enchendo disso. [/quote]

Ou seja, tu é noob, não sabe usar a ferramenta corretamente, usa um padrão de controle idiota e altamente não recomendado (OpenSessionInView) e ainda acha que a culpa é do Hibernate?

Você disse que não é recomendado usar o padrão OpenSessionInView, cara vai fazer uma faculdade.

Há… antes da faculdade aprenda logo a ler, porque em nenhum momento foi dito que a culpa é do hibernate.

[quote=morcego]Você disse que não é recomendado usar o padrão OpenSessionInView, cara vai fazer uma faculdade.

Há… e aprenda a ler também, porque em nenhum momento foi dito que a culpa é do hibernate.
[/quote]

Nem vou ligar para a sua agressividade gratuita. Eu sei ler, e na realidade nem estava falando de você, o quote que eu fiz o cara estava dizendo claramente que a culpa de não estar funcionando era sim do Hibernate. Bem Aqui ó:

[quote]Hibernate é uma bomba e uma carroça desenfreada…

Uma solução que precisa de várias soluções ou gambiarras não pode ser considerada uma solução.

Simplesmente não quero que ele salva automático ? E agora ? Tenho que fazer toda uma gambiarra pra burlar isso. [/quote]

Quanto a fazer um faculdade, ja está feita amigo.
Quanto ao Anti-Padrão Open Session in View:
http://stackoverflow.com/questions/1103363/why-is-hibernate-open-session-in-view-considered-a-bad-practice
http://blog.frankel.ch/the-opensessioninview-antipattern

E por ultimo e mais importante:
http://java.dzone.com/articles/opensessioninview-antipattern

Então, tenha calma na hora de responder, principalmente se você estiver iniciando em alguma coisa, as chances de você estar falando merda são mais de 8000;

Sei que nesse fórum a maioria das pessoas são sérias, por isso peço desculpas por ter que postar palavras em tom desagradável. Mas é que algumas pessoas só participam do Fórum para querer parecer superior e não em ajudar que é objetivo do Fórum.

Ainda aguardo resposta pela dúvida.

Até.

[quote=morcego]Sei que nesse fórum a maioria das pessoas são sérias, por isso peço desculpas por ter que postar palavras em tom desagradável. Mas é que algumas pessoas só participam do Fórum para querer parecer superior e não em ajudar que é objetivo do Fórum.

Ainda aguardo resposta pela dúvida.

Até.[/quote]

Ninguem é pago para te ajudar, e mesmo assim era o que eu estava tentando fazer. Você está buscando uma maneira de contornar um problema causado por um anti-padrão e eu estou te mostrando que o seu problema é o OSIV em si. Agora, você pode até tentar me atacar, se fazer de vitima como está fazendo. Ou pode assumir que estava errado e buscar uma solução melhor do que essa.

Eu estava falando deste quote:

Há e idiota é você.

[quote=morcego]Eu estava falando deste quote:

Há e idiota é você.[/quote]

PQP, eu acabei de colar sobre o que eu estava respondendo. Você, não sei por qual motivo, tomou as dores do cara. E sinceramente, não lembro de ter te chamado de idiota.

Tópico trancado devido a agressividade dos dois.