<< Duvida Criteria >>

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

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

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?

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

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

vc ta usando show_sql ? true ??

qual o sql q o hibernate esta montando ?

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?

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

[code]//ou isso

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

//ou isso

criteria.add(Restrictions.sqlRestriction("minha_funcao({estado.sigla}) like minha_funcao(?)", "CE", Hibernate.STRING));[/code]

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?

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.

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?