Hoje durante a utilização da api criteria para consultas dinâmicas enquanto realizava um curso, me deparei com uma coisa bem chata, no qual eu possuo 3 beans.
- Estado
- Cidade
- Usuário
Ocorria o seguinte inconveniente, devido essa consulta ser usada em filtros decidi usar o CriteriaBuilder pela facilidade em criar dinamicamente as consultas, porem todas as vezes que eu realizava uma consulta sempre recebia duas consultas adicionais, uma para Cidade e outra para Estado. E antes que me perguntem sim! marquei como lazy essas relações e não desejo nem quero que sejam JoinType Eager sempre, porem ao usar o CriteriaBuilder ele ignora completamente e volta a usar o lazy-loading.
select
cliente0_.codigo as codigo1_2_,
cliente0_.cpf_cnpj as cpf_cnpj2_2_,
cliente0_.email as email3_2_,
cliente0_.cep as cep4_2_,
cliente0_.codigo_cidade as codigo_11_2_,
cliente0_.complemento as compleme5_2_,
cliente0_.logradouro as logradou6_2_,
cliente0_.numero as numero7_2_,
cliente0_.nome as nome8_2_,
cliente0_.telefone as telefone9_2_,
cliente0_.tipo_pessoa as tipo_pe10_2_
from
cliente cliente0_
where
1=1 limit ?;
select
cidade0_.codigo as codigo1_1_0_,
cidade0_.codigo_estado as codigo_e3_1_0_,
cidade0_.nome as nome2_1_0_
from
cidade cidade0_
where
cidade0_.codigo=?;
select
estado0_.codigo as codigo1_3_0_,
estado0_.nome as nome2_3_0_,
estado0_.sigla as sigla3_3_0_
from
estado estado0_
where
estado0_.codigo=?
O que de fato não é nem de longe ideal para um bom desempenho, mas então oque fazer ? será que existe uma forma de incorporar na primeira query as duas adicionais ? E a resposta é sim! basta fazer o fetch , nas relações que deseja evitar as consultas adicionais, mesma coisa que fazemos no HQL.
Root cliente = querie.from(Cliente.class);
cliente.fetch(Cliente_.ENDERECO)//Representa o endereço
.fetch(Endereco_.CIDADE, JoinType.LEFT)//Realiza o Fetch de Cliente com Cidade
.fetch(Cidade_.ESTADO, JoinType.LEFT); //Realiza o Fetch da Cidade com estado
A partir de agora a consulta gerada é a seguinte.
select
cliente0_.codigo as codigo1_2_0_,
cidade1_.codigo as codigo1_1_1_,
estado2_.codigo as codigo1_3_2_,
cliente0_.cpf_cnpj as cpf_cnpj2_2_0_,
cliente0_.email as email3_2_0_,
cliente0_.cep as cep4_2_0_,
cliente0_.codigo_cidade as codigo_11_2_0_,
cliente0_.complemento as compleme5_2_0_,
cliente0_.logradouro as logradou6_2_0_,
cliente0_.numero as numero7_2_0_,
cliente0_.nome as nome8_2_0_,
cliente0_.telefone as telefone9_2_0_,
cliente0_.tipo_pessoa as tipo_pe10_2_0_,
cidade1_.codigo_estado as codigo_e3_1_1_,
cidade1_.nome as nome2_1_1_,
estado2_.nome as nome2_3_2_,
estado2_.sigla as sigla3_3_2_
from
cliente cliente0_
left outer join
cidade cidade1_
on cliente0_.codigo_cidade=cidade1_.codigo
left outer join
estado estado2_
on cidade1_.codigo_estado=estado2_.codigo
where
1=1 limit ?
Espero ter ajudado pessoas que assim como eu tiveram muitos problemas, para conseguir realizar esse simples procedimento assim como era feito no HQL.