Hibernate Criteria - filtrar por atributo

Oi pessoal,

Estou com a seguinte dúvida:

Tenho duas classes:

public class Curso{

private Integer id;
private String nome;
private Disciplina disciplinas;


metodos set e get

}

public class Disciplina{

private Integer id;
private String nome;
private String periodo; // pode ser “N” (noturno) ou “D” (diurno)


metodos set e get

}

Agora quero criar uma criteria que retorne um determinado curso e suas respectivas disciplinas. Estou usando o seguinte código:

Criteria select = sessao.createCriteria(Curso.class);
select.setFetchMode( “disciplinas”, FetchMode.JOIN );
select.add(Restrictions.like(“nome”, “Engenharia de Computacao”));

List objetos = select.list();

Até aqui tudo bem, funciona muito bem, ou seja, traz TODAS as disciplinas do curso “Engenharia de Computacao”.

Mas, a questão agora é que eu quero apenas as disciplinas de TAL curso que possuam o atributo periodo igual a “N” (noturno).

Já tentei fazer algo como:

Criteria select = sessao.createCriteria(Curso.class);
select.setFetchMode( “disciplinas”, FetchMode.JOIN );
select.add(Restrictions.like(“nome”, “Engenharia de Computacao”));
select.add(Restrictions.like(“curso.disciplinas.periodo”, “N”));

Mas é retornada a seguinte exceção:

Exception in thread “main” org.hibernate.QueryException: could not resolve property: curso of: tutorial.Curso

Alguém sabe como resolver isso ?

Pode ser também usando a Query em vez da Criteria, o importante é que eu consiga “filtrar” por um atributo de outra classe.

Muito obrigado

Marcos

Você irá precisar utilizar um Alias.

Criteria criteria = this.session.createCriteria(Curso.class);

	criteria.createAlias("disciplina", "dis");
		criteria.add(Expression.eq("nome", "Engenharia da computação"))
		criteria.add(Expression.eq("dis.periodo","N"))

	return 	criteria.list();

Isto deve funcionar. Contanto que seu mapeamento esteja correto.

Abraços…

Oi zepunk,

Obrigado pela resposta.

O uso do alias funciona sim, não gerou nenhuma exceção, mas ainda retorna todas as disciplinas do curso.

Utilizei inclusive:

select.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

Mas só faz efeito para os objetos da classe Curso.
Estou utilizando o MySQL, será que é algo relacionado a ele ?

Vc sabe algum outro “esquema” ?

Valew !!

Estou com um problema parecedo

  Criteria criteria = session.createCriteria(Funcionario.class);
    
        criteria.add(Expression.eq("nome", nome));

e fica dando o erro: eq(java.lang.String,java.lang.Object) in org.hibernate.criterion.Restriction cannot be appiled to (java.lang.String,nome)
Como resolver isto???

Brothers, salvaram meu dia…
Estava estressadasso por causa de um problema usando Criteria…
e faltava essa p3$$# do Alias…

Vou disponibilizar meu código para o caso de ajudar alguém futuramente 8)

[code]public List buscaCarga(String estadoOrigem , Cidade cidadeOrigem ,
String estadoDestino , Cidade cidadeDestino ,
CargaTipo tipoCarga , Especie especie ) {

    Session session = HibernateUtil.getSession();
    Criteria c = session.createCriteria(Frete.class);

    c.createAlias("cidadeOrigem", "origem"); 
    // se selecionar cidade então procure por cidade e não por estado, caso contrário por estado
    if(!ObjectUtil.isNull(cidadeOrigem)) {
        c.add( Restrictions.like("cidadeOrigem", cidadeOrigem) );
    } else if(!StringUtil.isEmptySelect(estadoOrigem)) {
        c.add( Restrictions.like("origem.uf", estadoOrigem) );
    }

    c.createAlias("cidadeDestino", "destino");
    // se selecionar cidade então procure por cidade e não por estado, caso contrário por estado
    if(!ObjectUtil.isNull(cidadeDestino)) {
        c.add( Restrictions.like("cidadeDestino", cidadeDestino) );
    } else if(!StringUtil.isEmptySelect(estadoDestino)) {
        c.add( Restrictions.like("destino.uf", estadoDestino) );
    }
    
    if(!ObjectUtil.isNull(tipoCarga)) {
        c.add( Restrictions.like("cargaTipo", tipoCarga) );
    }
    
    if(!ObjectUtil.isNull(especie)) {
        c.add( Restrictions.like("especie", especie) );
    }

    lista = c.list();
    return lista;
}[/code]

Eae Pessoal, estou com um problema de criteria tb…

Estou com uma aplicação java, com hibernate, banco em postgresql, e pegando uma surra básica com criteria e combos alinhados…

o negócio é o seguinte: estou tentando fazer a seguinte criteria:

@SuppressWarnings("unchecked") public List<Servico> getServicosId(Long id) { Criteria c = session.createCriteria(Servico.class); List<Servico> results = c.createCriteria("programa").add( Restrictions.like("cod_programa", id)).list(); //linha q gera a exception... return results; }

Esse método foi idéia de um colega aqui do GUJ que me ajudou a transformar uma query nessa linguagem acima…

a query era:

[code] @SuppressWarnings(“unchecked”)
public List getServicosByPrograma(Long id) {
Query q = session.createQuery("select c from “
+ Servico.class.getName()
+ " as c where c.programa.cod_programa like :id”);
q.setParameter(“id”, id);

	return q.list();
}[/code]

Só que me retorna esse erro:

[code]javax.servlet.ServletException: javax.servlet.ServletException: #{unidadeHandler.actionCarregaServicos}: org.hibernate.exception.SQLGrammarException: could not execute query
br.gov.rr.setrabes.util.HibernateSessionFilter.doFilter(HibernateSessionFilter.java:26)

org.postgresql.util.PSQLException: ERRO: operador não existe: bigint ~~ bigint
Dica: Nenhum operador corresponde com o nome e o(s) tipo(s) de argumento(s) informados. Você precisa adicionar conversões de tipo explícitas.
Posição: 317

br.gov.rr.setrabes.dao.ServicoDao.getServicosId(ServicoDao.java:41) // linha q eu marquei acima…
[/code]

Deve ser algum conflito entre do método com o Postgre, mas como eu sou iniciante em java e quase n tenho conhecimento com PostGre, ainda nao consegui descobrir o q é…
Se alguem puder ajudar, agradeço.

Qual o tipo do seu “id” no banco de dados?
Se puder coloque o SQL de criação da tabela serviço.
Até breve.

[quote=bbmany]Qual o tipo do seu “id” no banco de dados?
Se puder coloque o SQL de criação da tabela serviço.
Até breve.[/quote]

Graças a Deus uma abençoada pra me ajudar!!

:smiley:

segue a tabela:

CREATE TABLE programa
(
  cod_programa bigint NOT NULL,
  nome character varying(255),
  CONSTRAINT programa_pkey PRIMARY KEY (cod_programa)
)
WITH (OIDS=FALSE);
ALTER TABLE programa OWNER TO postgres;



CREATE TABLE servico
(
  cod_servico bigint NOT NULL,
  nome character varying(255),
  programa_cod_programa bigint,
  CONSTRAINT servico_pkey PRIMARY KEY (cod_servico),
  CONSTRAINT fk7643c6bf26b9a8f7 FOREIGN KEY (programa_cod_programa)
      REFERENCES programa (cod_programa) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (OIDS=FALSE);
ALTER TABLE servico OWNER TO postgres;

Agradeço a ajuda.

Kleber-rr
Acredito que o problema seja no cast
Tente desmembrar esta linha:

List<Servico> results = c.createCriteria("programa").add(Restrictions.like("cod_programa", id)).list();
Isto é, tente pegar apenas um resultado, para ver o que a consulta vai retornar.
Aguardo.

[quote=bbmany]Kleber-rr
Acredito que o problema seja no cast
Tente desmembrar esta linha:

List<Servico> results = c.createCriteria("programa").add(Restrictions.like("cod_programa", id)).list();
Isto é, tente pegar apenas um resultado, para ver o que a consulta vai retornar.
Aguardo.[/quote]

bbmany, eu resolvi com ajuda de um colega do guj em outro tópico, o problema era o like. Tinha q ser o eq no lugar.

List<Servico> results = c.createCriteria("programa").add(Restrictions.eq("cod_programa", id)).list();

Valeu a ajuda!!!

Que bom que resolveu!
Lembre-se de acrescentar [Resolvido] ao título do tópico.
Até breve.

[quote=bbmany]Que bom que resolveu!
Lembre-se de acrescentar [Resolvido] ao título do tópico.
Até breve.[/quote]

Como eu posso alterar o título do tópico??

ops, eu naum posso mudar o título pq o tópico naum é meu!!! huahuahauha

:smiley:

É verdade… desculpe :oops:

Q isso, tranquilo :smiley:

Tive um problema parecido e o alias de resolveu. Vlw.