Dúvida simples sobre Criteria e Alias

Olá!

Preciso fazer uma consulta com Criteria como no exemplo abaixo:

select * from atividade a
left join responsavel r on r.id = a.id_responsavel
left join cliente c on c.id = a.id_cliente
where r.id = 1 or c.id = 1

No caso, cada Atividade está mapeada com um Reponsável e um Cliente, e estou filtrando apenas as atividades que tenham responsável igual a 1 ou cliente igual a 1. Enfim, muito simples. Só que não consigo fazer a restrição. Fiz assim:

Criteria c = sessao.createCriteria(Atividade.class)
        .createAlias("responsavel", "r")
        .createAlias("cliente", "c")
        .add(
            Restrictions.or(
                 Restrictions.eq("r.id", 1),
                 Restrictions.eq("c.id", 1)
             )
        );

O resultado obtido não é o esperado. Aparentemente, quando crio o alias de “responsavel” e logo após o de “cliente”, o Hibernate aninha os dois, como se cliente estivesse “dentro” de responsável. Gostaria de saber como fazer para que isso não ocorra

Grato!

Cara tentou tirar os Alias?

Eu tenho um select parecido com o seu na minha app mas nem uso os alias nos atributos.

Criteria c = sessao.createCriteria(Atividade.class)  
        .add(  
            Restrictions.or(  
                 Restrictions.eq("responsavel.id", 1),  
                 Restrictions.eq("cliente.id", 1)  
             )  
        );  

Eu acho q quando vc da um createAlias vc esta se referenciando a tabela não aos atributos dela…

Obrigado pela resposta!

Eu poderia até tirar o alias, mas é que na verdade eu quero o id de um objeto dentro de responsável, por exemplo, responsavel.endereco.id. O Hibernate não permite uma property dessa profundidade, então tem que ser com Alias mesmo.

Responsavel e Cliente são duas tabelas do banco (além de propriedades do objeto), então não tem problema em usar o createAlias para referenciá-las.

Cara acredito q o Hibernate permita sim!

Eu tenho exatamente este código no meu projeto do http://www.loucaliza.com.br

Criteria crit = session.createCriteria(UsuarioAmigo.class);
crit.setProjection(Projections.rowCount());
crit.add(Restrictions.eq("id.usuario.id", id));
crit.add(Restrictions.eq("flgConfirmacao", flgConfirma));

Até dois nivel eu consigo usar sim, desde que seja busca por id…
No meu projeto de filtro faço isso numa boa!!

http://www.guj.com.br/posts/list/221618.java

Olá!

Coloquei novamente o segundo nível mais id, do jeito que está abaixo.

   Criteria c = sessao.createCriteria(Atividade.class)  
           .add(  
                Restrictions.or(  
                     Restrictions.eq("responsavel.endereco.id", 1),  
                     Restrictions.eq("cliente.id", 1)  
                 )  
            );  

No entando, o seguinte erro aparece:

org.hibernate.QueryException: could not resolve property: responsavel.endereco.id of: objeto.Atividade

Sim, está tudo mapeado corretamente nos arquivos de configuração e nos beans. Não consigo mais imaginar por que esse erro ocorre :roll:

acho que me expressei mal, queria dizer issu:

primeiro nivel:

 Restrictions.eq("id", 1)  //Atividade.id

eu consigo fazer até isso:

 Restrictions.eq("cliente.id", 1)  //Atividade.cliente.id

acima seria 3 nivel:

Restrictions.eq("responsavel.endereco.id", 1)  //Atividade.responsavel.endereco.id  

para buscar os parametros acima do 1 nivel só com Join, a ñ ser c for o id do segundo nivel, eu acho que tem como vc fazer os Join pelo criteria, ai funcionaria… Pesquise como adicionar os Join no criteria que vai funfar. Eu ñ me lembro mais seria algo assim:

.add( Restrictions.join("inner", "responsavel"))//é só pra entender + tem um jeito q eu j´vi em algum lugar + num lembro..

Obrigado pela ajuda de todos.

Acabei descobrindo a origem da minha dúvida. Antes achava que estava sendo criado um alias “dentro” de outro, mas não me ocorreu que o Hibernate faz um Inner Join por default quando se utiliza Criteria. A solução foi forçar o Left Join ao criar a Criteria:

Criteria c = sessao.createCriteria(Atividade.class)
                 .createAlias("cliente", "c", CriteriaSpecification.LEFT_JOIN);

Obrigado novamente pela ajuda. :slight_smile:

Bom dia caras!

Estou com um problema parecido com o que esta rolando aqui nesta pergunta…

[code] @Override
public List getListbyCriteriaBetween(Date of, Date to, String rg, String empresa, String acesso) {
List lista = new ArrayList();
Criteria criteria = session.createCriteria(classe);
criteria.createAlias(“pessoa”, “pessoa”, Criteria.INNER_JOIN, Restrictions.ilike(“pessoa.rg”, rg, MatchMode.ANYWHERE));
criteria.add(Restrictions.ilike(“pessoa.empresa”, empresa+"%", MatchMode.ANYWHERE)); //Até aqui beleza ele me retorna corretamente
criteria.add(Restrictions.ilike(“pessoa.acesso.Nome”, acesso)); // AQUI que dá a Merda… Acesso é uma Entidade que faz referencia com PESSOA
criteria.add(Restrictions.between(“dataVisita”, of, to));
criteria.addOrder(Order.desc(“idMovimento”));
lista = criteria.list();
return lista;

}[/code]

Porem não consigo acessar estaprofundidade! Alguém pode me dar uma luz referente a isto?

Muito Obrigado!

[quote=gabrieljah]Bom dia caras!

Estou com um problema parecido com o que esta rolando aqui nesta pergunta…

[code] @Override
public List getListbyCriteriaBetween(Date of, Date to, String rg, String empresa, String acesso) {
List lista = new ArrayList();
Criteria criteria = session.createCriteria(classe);
criteria.createAlias(“pessoa”, “pessoa”, Criteria.INNER_JOIN, Restrictions.ilike(“pessoa.rg”, rg, MatchMode.ANYWHERE));
criteria.add(Restrictions.ilike(“pessoa.empresa”, empresa+"%", MatchMode.ANYWHERE)); //Até aqui beleza ele me retorna corretamente
criteria.add(Restrictions.ilike(“pessoa.acesso.Nome”, acesso)); // AQUI que dá a Merda… Acesso é uma Entidade que faz referencia com PESSOA
criteria.add(Restrictions.between(“dataVisita”, of, to));
criteria.addOrder(Order.desc(“idMovimento”));
lista = criteria.list();
return lista;

}[/code]

Porem não consigo acessar estaprofundidade! Alguém pode me dar uma luz referente a isto?

Muito Obrigado![/quote]

Você está tentando acessar o acesso.Nome dentro da Pessoa sem fazer um join/alias, o correto deveria:

public List<T> getListbyCriteriaBetween(Date of, Date to, String rg, String empresa, String acesso) {
        List lista = new ArrayList();
        Criteria criteria = session.createCriteria(classe);
        criteria.createAlias("pessoa", "pessoa", Criteria.INNER_JOIN, Restrictions.ilike("pessoa.rg", rg, MatchMode.ANYWHERE));
        criteria.createAlias("pessoa.acesso", "acesso", Criteria.INNER_JOIN); //Ou outro Join, depende da sua necessidade
        criteria.add(Restrictions.ilike("pessoa.empresa", empresa+"%", MatchMode.ANYWHERE)); //Até aqui beleza ele me retorna corretamente
        criteria.add(Restrictions.ilike("acesso.Nome", acesso)); // AQUI que dá a Merda... Acesso é uma Entidade que faz referencia com PESSOA
        criteria.add(Restrictions.between("dataVisita", of, to));
        criteria.addOrder(Order.desc("idMovimento"));
        lista = criteria.list();
        return lista;

}

[]'s

1 curtida

Fala LeonHard!

Cara obrigado… desta forma deu certo para fazer a consulta.

Ficando desta forma:

[code] @Override
public List getListbyCriteriaBetween(Date of, Date to, String rg, String empresa, String acesso) {
List lista = new ArrayList();
Criteria criteria = session.createCriteria(classe);
criteria.createAlias(“pessoa”, “pessoa”, Criteria.INNER_JOIN, Restrictions.ilike(“pessoa.rg”, rg, MatchMode.ANYWHERE));
criteria.createAlias(“pessoa.acesso”, “acesso”, Criteria.INNER_JOIN);
criteria.add(Restrictions.ilike(“pessoa.empresa”, empresa+"%", MatchMode.ANYWHERE));
criteria.add(Restrictions.ilike(“acesso.nome”, acesso+"%", MatchMode.ANYWHERE));

    criteria.add(Restrictions.between("dataVisita", of, to));
    criteria.addOrder(Order.desc("idMovimento"));
    lista = criteria.list();
    return lista;

}[/code]

Porém eu preciso fazer esta chamada atrás do ID do ACESSO

Exemplo:

Alterando inicio do metodo. (String Acesso para Integer Acesso)

Parametros do acesso vindo daqui:

                                 <p:selectOneMenu id="acesso" value="#{mbRelatorio.acesso}" >
                                    <f:selectItem    itemLabel="Selecione..."/>
                                    <f:selectItems value="#{bbAcesso.acessos}" var="acesso" itemValue="#{acesso.idAcesso}" itemLabel="#{acesso.nome}"/>
                                </p:selectOneMenu>

Porem me retorna isso:

exception

javax.servlet.ServletException: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
root cause

javax.faces.el.EvaluationException: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer

tentei de diversas formas, mas não ta rolando! consegue me dar uma luz?

Abraçoo!

Olá,
Como faço para transformar o sql abaixo, num createCriteria?

select * from produto pr left join publicacao pu on pr.produtoid=pu.publicacaoid left join ebook eb on eb.ebookid=pu.publicacaoid order by pr.produtoid