1. java
  2. android
  3. c#
  4. .net
  5. javascript
  6. php
  7. jquery
  8. html
  9. sql

Como fazer essa consulta com Criteria Hibernate envolvendo uma Collection?

Class Entidade {
List<Integer> valores;
}

Como posso fazer uma pesquisa com Criteria Hibernate que retorne as entidades que atendam as seguintes condições?

valores[0] = valor1
valores[1] = valor2
valores[2] = valor3

To quebrando a cabeça aqui, mas não consigo imaginar como posso fazer isso com Criteria.

Obs: Meu mapeamento está funcionando, consigo persistir e buscar os objetos, somente neste caso que não estou conseguindo.

Edit2:

No banco de dados as tabelas geradas pelo hibernate estão assim:

tabela 1
Nome: Entidade
campo1: codigo

tabela 2
Nome: Valores
campo1: cod_entidade 
campo2: valor

Edit3

Mapeamento da classe está assim:

@Entity
public class Entidade {

    @Id
    @GeneratedValue
    long codigo;

@ElementCollection(fetch = FetchType.EAGER)
    @CollectionTable(name = "Valores", joinColumns = @JoinColumn(name = "cod_entidade"))
    @Column(name = "valor")
    private List<Integer> valores = new ArrayList<Integer>();
}

Edit4:

Tentei fazer com HQL

ArrayList<Integer> valores = new ArrayList<Integer>();
        valores.add(300);
        valores.add(400);
        valores.add(500);


lista = session.createQuery("from Entidade where valores in ( :list)").setParameter("list", valores).list();

Mas me retornou a exception:

org.hibernate.exception.SQLGrammarException: No value specified for parameter 1

E o SQL gerado pelo hibernate: (dei uma ajeitada nos nomes)

SELECT e.codigo as CodigoEntidade 
FROM Entidade e 
CROSS JOIN Valores v
WHERE e.codigo=v.cod_entidade 
AND ({non-qualified-property-ref} in (?))

Edit5

Tentativa com o criteria

ArrayList<Integer> valores = new ArrayList<Integer>();
        valores.add(300);
        valores.add(300);
        valores.add(300);

        Criteria crit = session.createCriteria(Entidade.class);
        crit.add(Restrictions.in("valores", valores));

Expection retornada:

org.hibernate.exception.SQLGrammarException: No value specified for parameter 1

SQL gerada:

select e.codigo as EntidadeCodigo, 
v.cod_entidade as cod_entidade, 
v.valor as valor 
from Entidade e 
left outer join Valores v 
on e.codigo=v.cod_entidade 
where e.codigo in (?, ?, ?)

Edit6

O SQL puro que deveria gerar é isso: testei diretamente no banco e funcinou, só que agora preciso mapear isso para HQL ou criteria.

select e.codigo as EntidadeCodigo
from unicbox.entidade e 
left outer join unicbox.valores v 
on e.codigo=v.cod_entidade 
where v.valor in (300, 300, 300)

Edit7

A Cláusula IN vai pesquisar todas as entidades que contem qualquer valor informado na lista de valores, mas eu preciso das entidades que tenham os três valores que informei na lista, e na mesma ordem de inserção

Edit8

Em sql puro consegui fazer busca do jeito que eu quero porém agora tenho que descobrir como mapear isso ao criteria:

SELECT e.codigo FROM entidade AS e 
WHERE( SELECT group_concat(valor) 
        FROM valores 
        WHERE cod_entidade = e.codigo 
        GROUP BY cod_entidade) 
        = "100,15,200";
  • Devo estar tetando fazer algo impossível, só pode

    netoSJB   12 de jun de 2013
  • É necessário que seja usado Criteria? Pode ser que, pelo fato de ela ter algumas limitações, isso não seja possível(de acordo com meu conhecimento). Se puder ser um hql, eu posso arriscar um palpite.

    Leonardo Wolter   12 de jun de 2013
  • me passa o palpite em hql mesmo, porque criteria vou deixar apenas para as query mais simples

    netoSJB   12 de jun de 2013
  • segue o retorno da query criada pelo hibernate utilizando o HQL conforme o seu exemplo (dei uma arrumadinha nos nomes só para ficar entendivel) :

    SELECT e.codigo as CodigoEntidade FROM Entidade e CROSS JOIN Valores v WHERE e.codigo=v.cod_entidade AND ({non-qualified-property-ref} in (?))

    netoSJB   13 de jun de 2013
  • @netoSJB tente fazer um join na mao. Atualizei minha resposta desse modo.

    Leonardo Wolter   13 de jun de 2013
Mostrar todos os 6 comentários>
  1. Você vai ver essas setas em qualquer página de pergunta. Com elas, você pode dizer se uma pergunta ou uma resposta foram relevantes ou não.
  2. Edite sua pergunta ou resposta caso queira alterar ou adicionar detalhes.
  3. Caso haja alguma dúvida sobre a pergunta, adicione um comentário. O espaço de respostas deve ser utilizado apenas para responder a pergunta.
  4. Se o autor da pergunta marcar uma resposta como solucionada, esta marca aparecerá.
  5. Clique aqui para mais detalhes sobre o funcionamento do GUJ!

3 respostas

Não é a resposta que estava procurando? Procure outras perguntas com as tags hibernate java jpa ou faça a sua própria pergunta.