<< Duvida Criteria >>

10 respostas
T

Olá turma,

Estou com uma uma duvida em uma consulta usando critéria. Quando executo a consulta da linha 1 a 4, o processo é concluído com sucesso. Porém eu preciso chamar uma função do BD (minha_funcao), aí comento a linha 4 e executo a consulta da linha 1 a 5. Ocorre um erro: “ERROR: invalid reference to FROM-clause entry for table “estado””. Observando o sql gerado, verifiquei que o Hibernate gera um alias para o estado (estado1_) e não consegue colocar esse alias na expressão: ‘minha_funcao(estado.sigla) …’. e por isso ocorre.

Alguém tem ideia de como resolver? Existe outra forma de chamar uma função do BD?

Session session = (Session) em.getDelegate();
Criteria criteria = session.createCriteria(Cidade.class, "cidade");
criteria.createCriteria("cidade.estado","estado");
criteria.add(Expression.eq("estado.sigla", "CE"));
criteria.add(Restrictions.sqlRestriction("minha_funcao(estado.sigla) like minha_funcao(?)", "CE",  Hibernate.STRING));

10 Respostas

Lavieri

tenta isso =>

Session session = (Session) em.getDelegate(); Criteria criteria = session.createCriteria(Cidade.class, &quot;cidade&quot;); criteria.createCriteria(&quot;cidade.estado&quot;,&quot;estado&quot;); criteria.add(Expression.eq(&quot;estado.sigla&quot;, &quot;CE&quot;)); criteria.createAlias(&quot;estado.sigla&quot;, &quot;UF&quot;); //apelidando a sigla criteria.add(Restrictions.sqlRestriction(&quot;minha_funcao(UF) like minha_funcao(?)&quot;, &quot;CE&quot;, Hibernate.STRING));

T

Colocando essa linha:

Ocorre o seguinte erro: SEVERE: org.hibernate.QueryException: not an association: sigla

Pelo que percebi, o createAlias serve para criar apelidos para junções entre tabelas. Nesse caso a ‘sigla’ é uma propriedade e por isso o erro ocorre.

Alguém tem mais alguma dica?

Lavieri

provavelmente então, vc tera q usar o nome original das suas tabelas e campos, ja que esta tentanod usar uma instrução SQL…

T

Mais eu já estou fazendo isso. No meu caso os nomes das Classes e das suas respectivas propriedades correspondem com o BD. :frowning:

Lavieri

vc ta usando show_sql ? true ??

qual o sql q o hibernate esta montando ?

T

Segue abaixo o select gerado pelo Hibernate

select this_.id as id4_1_, this_.estado_id as estado3_4_1_, this_.nome as nome4_1_, estado1_.id as id13_0_, estado1_.nome as nome13_0_, estado1_.sigla as sigla13_0_ from Cidade this_ inner join Estado estado1_ on this_.estado_id=estado1_.id where minha_funcao(estado.sigla) like minha_funcao(?)

Fiz testes com ele diretamente no BD e simplesmente trocando (estado.sigla) por (estado1_.sigla) funciona tranquilo. Ou seja, o problema é que realmente o Hibernate não consegue traduzir o alias gerado dinamicamente.

Alguma sugestão?

Lavieri

la na API fala o seguinte...

Apply a constraint expressed in SQL, with the given JDBC parameter. Any occurrences of {alias} will be replaced by the table alias.

tenta isso aqui

criteria.add(Restrictions.sqlRestriction(&quot;minha_funcao({estado}.sigla) like minha_funcao(?)&quot;, &quot;CE&quot;,  Hibernate.STRING)); // &lt;== quase 100% de certeza que esse aqui é que funciona
//ou isso

criteria.add(Restrictions.sqlRestriction(&quot;minha_funcao({estado}.{sigla}) like minha_funcao(?)&quot;, &quot;CE&quot;,  Hibernate.STRING));

//ou isso

criteria.add(Restrictions.sqlRestriction(&quot;minha_funcao({estado.sigla}) like minha_funcao(?)&quot;, &quot;CE&quot;,  Hibernate.STRING));
T

Não rola não. O Select é gerado da seguinte forma:

No 1° caso: … where minha_funcao ({estado}.sigla) like minha_funcao (?)

No 2° caso: … where minha_funcao ({estado}.{sigla}) like minha_funcao (?)

No 3° caso: … where minha_funcao ({estado.sigla}) like minha_funcao (?)

Percebi que o método: ?Restrictions.sqlRestriction? não consegue traduzir nenhum alias. Se eu uso o ?Expression.eq? aí sim dar certo, o alias é traduzido, porém não consigo chamar as função do BD.

Acho que talvez o caminho seja verificar uma outra forma de chamar uma função do BD usando Hibernate…

Alguém tem mais alguma idéia?

geidivan

Cara, o que eu fiz aqui para dar certo foi dar o mesmo nome da variável do banco para o atributo da minha classe pojo.

Banco: cdpc.peca.num_refpad

Classe pojo:

@Entity
@Table(name="peca", schema="cdpc")
public class Peca implements Serializable {

    ....
   @Column(name="num_refpad")
    private int num_refpad;
    ....
}

Então, no criteria, coloquei apenas o nome da coluna:

crit.add(Restrictions.sqlRestriction("cp.num_refpadraocolor(num_refpad) = ?", p.getNum_refpad(), Hibernate.INTEGER));

Só consegui quando os nomes são iguais, perceba que nem precisei inserir o nome da tabela no sqlRestriction, só o schema da minha função, pois ela está em um schema diferente da minha tabela.

Tentei usar alias, mas não consegui. Veja se assim dá certo.

T

Mais eu também uso o mesmo nome. No meu sistema as tabelas e atributos do BD têm o mesmo nome do POJO. Esse seu deve ter dado certo, pois você deve ter feito uma busca simples, ou seja, sem utilizar Join.

Observe o código que postei, lá faço uma junção entre cidade e estado, e quero buscar por uma propriedade de estado, sendo que cidade é a “dona” do critério de busca. Aí não funfa de forma alguma.

Alguma outra dica?

Criado 6 de maio de 2009
Ultima resposta 21 de mai. de 2009
Respostas 10
Participantes 3