Dúvida simples sobre Criteria e Alias

11 respostas
C

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!

11 Respostas

F

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…

C

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.

F

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));
P

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

C

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:

P

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..

C

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:

G

Bom dia caras!

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

@Override
    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.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  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;

    }

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

Muito Obrigado!

L
gabrieljah:
Bom dia caras!

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

@Override
    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.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  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;

    }

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

Muito Obrigado!

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

G

Fala LeonHard!

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

Ficando desta forma:

@Override
    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);
        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;

    }

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

Exemplo:

criteria.add(Restrictions.ilike("acesso.idAcesso", acesso+"%", MatchMode.ANYWHERE));
Alterando inicio do metodo. (String Acesso para Integer Acesso)
public List<T> getListbyCriteriaBetween(Date of, Date to, String rg, String empresa, 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!

I

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

Criado 26 de novembro de 2010
Ultima resposta 18 de nov. de 2015
Respostas 11
Participantes 6