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, "cidade");
criteria.createCriteria("cidade.estado","estado");
criteria.add(Expression.eq("estado.sigla", "CE"));
criteria.createAlias("estado.sigla", "UF"); //apelidando a sigla
criteria.add(Restrictions.sqlRestriction("minha_funcao(UF) like minha_funcao(?)", "CE", 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. 
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?