ThreadLocal problema Transaction com OneToMany[Resolvido]

3 respostas
R

Galera estou mudando o projeto aqui para Thread Local no hibernate. É um projeto utilizando Java e Flex. Para não entrar em maiores detalhes, toda vez que altero um objeto e o comito, busca novamente esse objeto no banco.

Tenho uma classe empenho que possui uma coleção de itens. Toda vez que incluo um novo item, quando volto à tela de empenho busco novamento o objeto empenho para que os dados do item recém incluido alimentem o Grid. Algumas vezes, não todas, na busca o objeto que acabei de incluir, alterar ou excluir não vem atualizado, quando saio da tela e volto (carrego novamente) ele vem correto acredito que seja alguem problema de controlo de transação na busca. Estou colocando abaixo o código de busca

public Object buscarUm(Object consulta, Session s) throws SQLException {
        if (getSession() == null){
           setSession(sapiturSF.getInstance());
        }else{
        	if(!getSession().isOpen()){
        		setSession(sapiturSF.getInstance());
        	}
        }

        if(!getSession().getTransaction().isActive()){
        	 if(getTx() == null){
             	setTx(getSession().beginTransaction());
             }else{
             	if(!getTx().isActive()){
             		setTx(getSession().beginTransaction());
             	}
             }
        }
        Query query = getSession().createQuery((String) consulta);
        return query.uniqueResult();
    }

Agradeço a qualquer ajuda

3 Respostas

victorwss

Para que serve o parâmetro s se você usa getSession() dentro do método ou seta a sessão com o seu sapiturSF.getInstance()? Em lugar nenhum você usa o parâmetro s.
Porque você usa em um ponto getSession().getTransaction() e em outro usa getTx()? Isso não pode te dar um resultado inconsistente?

E eu otimizaria este código evitando repetições (e talvez você acabe matando alguns bugs ao fazer isso).
Por exemplo, isto daqui:if (cond1) { faz alguma coisa } else { if (cond2) { faz alguma coisa } }Pode ser simplificado nisso:if (cond1 || cond2) { faz alguma coisa }E isto daqui:if (cond1) { if (cond2) { faz alguma coisa } else { if (cond3) { faz alguma coisa } } }Pode ser simplificado nisso:if (cond1 && (cond2 || cond3)) { faz alguma coisa }

R

Ah sim claro, esqueci de comentar que realmente o parametro Session s não está sendo usado.
Esse parametro era usado na arquitetura antiga, que estava bem errada com dois métodos uma passando a Session e outro não.
Até depois resolvi usar, para não ficar tão diferente de como estava antes, a diferença é que se o cara já passar a sessão, eu não limpo não comito nem nada. Como estava tentando fazer o código funcionar não me preocupei mto com a organização. Mas, agora pelo menos com essas modificações “parece” estar funcionando:

if(s == null){
        	//Obtém a sessão
        	if (getSession() == null){
               setSession(sapiturSF.getInstance());
            }else if(!getSession().isOpen()){
            	setSession(sapiturSF.getInstance());
            }
            //Seta a transação como a transação da sessão
        	setTx(getSession().getTransaction());
            //Verifica se a sessão não está suja (necessita comitar)
        	if(getTx().isActive() && getSession().isDirty()){
            	getSession().getTransaction().commit();
            	setSession(sapiturSF.getInstance());
            	setTx(getSession().beginTransaction());
            //Verifica se a transação está inativa
        	}else if(!getTx().isActive()){
            	setTx(getSession().beginTransaction());
            }
        }else{
        	if(!s.isOpen()){
	      		s = sapiturSF.getInstance();
	      	}
        	setSession(s);
        }
    	
        //Chama a query
    	Query query = getSession().createQuery((String) consulta);
        return query.uniqueResult();

Agora é testar e ver se funciona mesmo, qualquer coisa posto aqui. Obrigado

R

Galera, tá resolvido. Parece que o flush que o commit dá não estava funcionando em todos os casos, foi só dar um flush nas sessões dirty que funcionou. Vou colocar aqui a solução, caso venha ajudar alguem:

private void montarSession(Session s) throws SQLException{
    	if(s == null){
        	//Obtém a sessão
    		if (getSession() == null || !getSession().isOpen()){
               setSession(sapConsolidacaoSF.getInstance());
            }
    		
            //Seta a transação como a transação da sessão
        	setTx(getSession().getTransaction());
            //Verifica se a transação está suja
        	if(!getTx().isActive()){
        		setTx(getSession().beginTransaction());
        	//Verifica se a sessão não está suja (necessita comitar)
        	}else if(getSession().isDirty()){
        		getSession().flush();
        		setTx(getSession().beginTransaction());
    		}
        }else{
        	if(!s.isOpen()){
	      		s = sapConsolidacaoSF.getInstance();
	      		if(!s.getTransaction().isActive()){
	      			setTx(s.beginTransaction());
	      		}
	      	}
        	setSession(s);
        }
    }
Criado 4 de março de 2011
Ultima resposta 10 de mar. de 2011
Respostas 3
Participantes 2