SubQuery utilizando Criteria/DetachedCriteria

Pessoal to com uma dúvida em relação a fazer uma pesquisa utilizando restrições do criteria. Utilizo criteria com paginação(PageWrapper) de 10 em 10 para trazer os itens com melhor performance.

Tenho 3 tabelas inicialmente

-BO (onetoMany para “bonat”, possuo a lista de BOnat)
-BONat (ManytoOne para bo, possuo o fkbo, e ManytoOne para nat, possuo o fknat)
-Nat (OnetoMany para “bonat”, possuo a lista de BoNat)

Onde eu aplico na minha classe de criteria

Criteria criteria = manager.unwrap(Session.class).createCriteria(Bo.class);

Ou seja faço minhas consultas, retornos e restrições tudo em cima da tabela BO

Possuo um filtro onde passo um ID da tabela NAT e tenho que trazer todos os registros de BO, onde consegui fazer da seguinte maneira utilizando o DetachedCriteria

DetachedCriteria filtroNatureza = DetachedCriteria.forClass(BoNatureza.class);
filtroNatureza.setProjection(Property.forName(“bo”));
filtroNatureza.add(Restrictions.eq(“natureza.idNatureza”, filtro.getNaturezaFato()));
criteria.add(Subqueries.propertyIn(“idBo”, filtroNatureza));

Ou seja crio um DetachedCriteria de Bonatureza pois la tenho o fknatureza
crio uma projecao do objeto bo que tenho em bonatureza
adiciono a restrição acessando minha fknatureza para filtrar o id que recebo no filtro
e adiciono no meu criteria a subquery.

Porém eu tenho mais outra tabela chamada envolvimento
onde ela é manytoOne para tabela “bonat” e quero acessar um fk dentro dessa tabela envolvimento, tentei utilizar o mesmo raciocínio acima mas não funcionou =(

Erick, mesmo que consiga isso fica ilegível para manter. Para querys complexas prefira SQL diretamente, muito mais prático. HQL seria um meio-termo para quem prefere query por objetos.

Sobre o que fez, posta o SQL que esse Criteria está gerando.

Criando uma consulta hql diretamente eu teria como adicionar no meu criteria (criteria.add…) e ele retornaria minha lista de resultados normalmente? Mesmo essa tabela não estando relacionada diretamente com a que criteria utiliza?

Não sei se entendi, mas minha sugestão não foi para misturar. Se decidir usar HQL, monte tudo via HQL, que faz a query em cima das associações do seu modelo orientado a objetos, assim como acontece com Criteria, só muda a forma de fazer. Se quiser se basear em tabelas, use SQL que é muito mais fácil e eficiente, sem precisar de linguagens intermediárias.

Na verdade utilizo o criteria pois monto a paginação em cima dela, e o criteria ja me retorna os resultados em cima da minha entidade, dai tenho um filtro onde faço as restrições dentro do criteria, porém tem uma restrição (que vem atraves do filtro ) que ta em uma tabela la do outro lado do banco, e utilizando as restrictions do criteria eu não consigo alcançar um parâmetro lá do outro lado.

Tem que associar no seu modelo de classes para conseguir chegar lá de forma limpa pelos relacionamentos.

Explicando o contexto…

Esse era o problema que eu tava enfrentando pq tava fazendo o criteria em cima da entidade BO
então eu retornava só o BO com os criterios que teoricamente tavam sendo requeridos so pra entidade de BO. Mas ai tive que adicionar um parametro no filtro, que teria que pesquisar pelo id_natureza da tabela natureza, so consegui fazer isso utilizando o código

DetachedCriteria filtroNatureza = DetachedCriteria.forClass(BoNatureza.class);
filtroNatureza.setProjection(Property.forName(“bo”));
filtroNatureza.add(Restrictions.eq(“natureza.idNatureza”, filtro.getNaturezaFato()));
criteria.add(Subqueries.propertyIn(“idBo”, filtroNatureza));

assim eu consegueria acessar o objeto “bo” dentro de BoNatureza, e passar a restrição igualando o idNatureza, depois fazendo a subquerie e adicionando ao criteria. isso funcionou ok.

O problema…

O problema é que agora eu tenho que fazer uma pesquisa passando por mais duas tabelas…

Tenho que passar o nome da pessoa que ta na tabela pessoa que por sua vez tem fk_pessoa_fisica (tabela pessoa fisica que nao aparece na imagem) e la filtrar pelo nome por exemplo, e assim trazer os dados da tabela “bo”

Via HQL ou Criteria tem que se basear nas associacoes do modelo de classes. Para atender o modelo do banco relacional basta usar SQL.

Sim estou usando o modelo de classes o problema que ele não consegue “alcançar” a tabela pela qual preciso fazer a restrição.

Se quer fazer join com outra tabela, o alcance é determinado pelo mapeamento do banco com seu modelo de classes.

Acredito que do jeito que foi mapeado eu acho que nao consigo acessar X pessoa =(