[resolvido] ajuda com o hashset e sub criteria (hibernate)

8 respostas
B

Ola amigos do GUJ,

Pessoal estou com um problema no o uso do criteria eu consigo retorna os nomes q comecao com B "B%" mais depois na hora de exibir no meio do loop o hibernate é ativado novamente e retorna todos os telefones sem a restricao do prefixo "(11)%" ... creio q ele esta perdendo a consulta anterior e realizando uma nova só com na tabela telefone e sem restricao.

Obs: Ao perceber eu marquei o trecho ao acontece essa nova chamada do hibernate usando essas linhas:
System.out.println("\n---------------------------------------------");
System.out.println(u.getCNome() + " *Dentro do Objeto Nº: " + i++);

Segue os Codigos:

Trecho do hashset da classe TbUsuario:
private Set tbTelefones = new HashSet(0);

 public Set getTbTelefones() {
        return this.tbTelefones;
    }
    
    public void setTbTelefones(Set tbTelefones) {
        this.tbTelefones = tbTelefones;
    }
Classe DAO:
List results =
                    session.createCriteria(TbUsuario.class)
                    .createAlias("tbTelefones", "tel")
                    .add(Expression.like("this.CNome", "B%"))
                    .add(Expression.like("tel.CTelefone", "(11)%"))
                    .list();                   

           List<TbUsuario> lista_usuario = results;

            //cria o objeto telefone
            TbTelefone telefone;

            Integer i = 0;
            //percorre a lista
            for (TbUsuario u : lista_usuario) {
                System.out.println("\n---------------------------------------------");
                System.out.println(u.getCNome() + " *Dentro do Objeto : " + i++);

                //* ESSA LINHA GERA MAIS UMA CONSULTA DO HIBERNATE E RETORNA TODOS OS TELEFONES
                Iterator It = u.getTbTelefones().iterator();
                int n = 0;
                while (It.hasNext()) {

                    telefone = (TbTelefone) It.next();
                    System.out.println(telefone.getCTelefone());

                }
Mapeamento xml do usuario:
<set inverse="true" name="tbTelefones">
      <key>
        <column name="c_id_usuario"/>
      </key>
      <one-to-many class="Modelo.TbTelefone"/>
    </set>
Mapeamento xml do telefone:
<many-to-one class="Modelo.TbUsuario" fetch="select" name="tbUsuario">
      <column name="c_id_usuario"/>
    </many-to-one>
Resultados exibidos no console: Hibernate: select this_.c_id as c1_1_1_, this_.c_nome as c2_1_1_, this_.c_email as c3_1_1_, tel1_.c_id as c1_0_0_, tel1_.c_id_usuario as c2_0_0_, tel1_.c_telefone as c3_0_0_ from public.tb_usuario this_ inner join public.tb_telefone tel1_ on this_.c_id=tel1_.c_id_usuario where this_.c_nome like ? and tel1_.c_telefone like ?

---------------------------------------------
Bruno *Dentro do Loop Objeto Nº: 0
Hibernate:
select
tbtelefone0_.c_id_usuario as c2_1_,
tbtelefone0_.c_id as c1_1_,
tbtelefone0_.c_id as c1_0_0_,
tbtelefone0_.c_id_usuario as c2_0_0_,
tbtelefone0_.c_telefone as c3_0_0_
from
public.tb_telefone tbtelefone0_
where
tbtelefone0_.c_id_usuario=?
([telefone removido]
([telefone removido]
([telefone removido]

Obrigado pela atenção. 8)

8 Respostas

Lavieri

a sua consulta pega os usuários que tem nome inicando em B, e que tem telefone inicnado em (11)%

ate ai tudo bem...

depois vc percorre os usuários que vc recebeu, e acessa a propriedade Telefones do usuário, essa propriedade ter retorna todos os telefones do usuário o que esta correto...

Se o que vc ker é o contrario, ker saber só os telefones com o número desta forma vai ter q fazer outra abordagem...

List results =  
             session.createCriteria(TbTelefone.class)  
             .createAlias("tbUsuario", "usr")  
             .add(Expression.like("usr.CNome", "B%"))  
             .add(Expression.like("this.CTelefone", "(11)%"))  
             .list();                     
      
    List&lt;TbTelefone&gt; lista_usuario = results;
B

Ola Lavieri,
Fiz o que vc falou mais o resultado nao saiu muito bom vendo pela classe java o hibernate cria uasndo HashSet acho q eu na to sabendo usa la por isso q a primeira tentativa nao deu muito certo.

List results =
             session.createCriteria(TbTelefone.class)
             .createAlias("tbUsuario", "usr")
             .add(Expression.like("usr.CNome", "B%"))
             //.add(Expression.like("this.CTelefone", "(11)%"))
             .list();

            List<TbTelefone> lista_usuario = results;

                       //cria o objeto telefone

   
            TbTelefone telefone;

            Integer i = 0;
       
            for (TbTelefone tel : lista_usuario) {
                System.out.println("\n---------------------------------------------");
                System.out.println(tel.getTbUsuario().getCNome() + " *Dentro do Objeto : " + i++);

                 System.out.println("Tel: "+tel.getCTelefone());
            }

O console exibi:

Bruno *Dentro do Objeto Nº: 0
Tel: ([telefone removido]


Bruno *Dentro do Objeto Nº: 1
Tel: ([telefone removido]

Lavieri

esse era exatamente o resultado esperado…

vc pegou a lista de telefones, e imprimiu cada telefone e imprimiu o dono do telefone…

na outra consulta vc pegava os donos do telefone, e depois exibia sua lista de telefones totais, e não apenas os mesmos do seu filtro

B

Como eu posso retornar nesse formato:

Bruno

Tel: ([telefone removido]
Tel: ([telefone removido]

Porque no formato q ele retorna eu vo ter q criar uma gambiarra para comparar o id do objeto…

Saida do console com o id:


Bruno Objeto Nº: 0
ID: 2
Tel: ([telefone removido]


Bruno Objeto Nº: 1
ID: 2
Tel: ([telefone removido]

Lavieri

vc pode fazer 2 coisas... ou rodar um loop... e guardar os objetos organizadamente em um mapa, tentar essa arbodagem

List mapas = sess.createCriteria(TbUsuario.class)
    .createCriteria("tbTelefones", "tel")
        .add( Restrictions.like("this.CNome", "B%") )
        .add( Restrictions.like("tel.CTelefone", "(11)%") )
        .addOrder(Order.asc("this.Cnome"));
    .setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP)
    .list();
Iterator iter = mapas.iterator();
TbUsuario old = null;
Integer i = 0; 
while ( iter.hasNext() ) {
    Map map = (Map) iter.next();
    TbUsuario usuario = (TbUsuario) map.get(Criteria.ROOT_ALIAS);
    TbTelefone telefone = (TbTelefone) map.get("tel");

    if (!usuario.equals(old)) { //so imprime o cabeçalho c for pessoa diferente
         System.out.println("\n---------------------------------------------");
         System.out.println(usuario.getCNome() + " *Dentro do Objeto : " + i++);
    }
    
    System.out.println(telefone.getCTelefone());
    
    old = usuario;
}

pronto ai vc adapta pra ficar como vc quer... essa consulta pega os 2 objetos que vc precisa pra imprimir

B

Lavieri

A Criteria fico melhor mesmo mais o resultado final foi esse nao sai no formato q eu queria:


Bruno Objeto Nº: 0
([telefone removido]


Breno Objeto Nº: 1
([telefone removido]


Bruno Objeto Nº: 2
([telefone removido]

Geralmente o pessoal usa criteria no hibernate?

B

Lavieri agora foi acho q vc atualizo o reply depois ^^

Obrigado pela ajuda agora vo estuda o que vc fez aqui pq estou comecando em hibernate.

Saida do console:


Breno Objeto Nº: 0
([telefone removido]


Bruno Objeto Nº: 1
([telefone removido]
([telefone removido]

Lavieri

BrunoPunk:
Lavieri agora foi acho q vc atualizo o reply depois ^^

Obrigado pela ajuda agora vo estuda o que vc fez aqui pq estou comecando em hibernate.

Saida do console:


Breno Objeto Nº: 0
([telefone removido]


Bruno Objeto Nº: 1
([telefone removido]
([telefone removido]

editei mas muito antes de vc postar, editei o sort, que estava faltando, pra ele manter as pessoas juntas…

o que fiz foi agrupar os resultados em um mapa…

Sim a turma usa muito criteria sim, pq é melhor q montar sqls, hqls, jpa qls etc…

se quer estudar como fazer => http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querycriteria.html

Criado 14 de outubro de 2009
Ultima resposta 14 de out. de 2009
Respostas 8
Participantes 2