Subquery com JPA Criteria

Bom dia amigos.

Estou com um problema para validar o nosso cadastro de usuarios, através do JPA Criteria, contra as tabelas de CEP fornecidas pelo correio e descobrir quantos clientes possuem o cep inválido. As tabelas principais do correio são a de logradouro e localidade (esta guarda os de municipios com cep único). Esta consulta seria resolvida de maneira simples com SQL.

 SELECT a.* FROM YY_CLIENTE.CLIENTE A  
 LEFT JOIN YY_CEP.LOG_LOCALIDADE B ON A.ENDERECO_CEP = B.CEP 
 LEFT JOIN YY_CEP.LOG_LOGRADOURO C on A.ENDERECO_CEP = C.CEP  
 WHERE (B.CEP IS NULL AND C.CEP IS NULL) and a.bloqueio_cod = 31;

Porém, a arquitetura da empresa não me permite usar JDBC e nem queries nativas. Aí começam os meus problemas…
Do jeito que as classes foram modeladas, eu não tenho um Path que relaciona o cep’s das tabelas de cep para o cep do endereco do cliente, ou seja, pelo Criteria eu não tenho como fazer o Join. A solução seria então fazer uma subquerie:

SELECT count(a.id) FROM YY_CLIENTE.CLIENTE A 
WHERE a.ENDERECO_CEP  not in (select cep from YY_CEP.LOG_LOCALIDADE where cep is not null)
and  a.ENDERECO_CEP  not in (select cep from YY_CEP.LOG_LOGRADOURO where cep is not null)
and a.bloqueio_cod = 31

Até aí nem um mistério, o problema está quando uso o JPA

 CriteriaBuilder cb = entityManager.getCriteriaBuilder();
 CriteriaQuery<Long> cq = cb.createQuery(Long.class);
 Root<Cliente> rt = cq.from(Cliente.class);
 Path<Long> cep = rt.get(Cliente_.endereco).get(EnderecoImovel_.cep);
       
 cq.select(cb.count(rt));
        
 Subquery<Long> subquery = cq.subquery(Long.class);
 Root<CepLogradouro>subRoot = subquery.from(CepLogradouro.class);
 subquery.select(subRoot.get(CepLogradouro_.cep).as(Long.class));
        
 Subquery<Long> subquery2 = cq.subquery(Long.class);
 Root<CepLocalidade>subRoot2 = subquery.from(CepLocalidade.class);
 subquery2.select(subRoot2.get(CepLocalidade_.cep).as(Long.class));
        
 cq.where(
         cb.not(cb.in(cep).value(subquery)),
         cb.not(cb.in(cep).value(subquery2)),
         cb.equal(rt.get(Cliente_.bloqueioCod), cb.literal("31"))

Long count = entityManager.createQuery(cq).getSingleResult();
);

Este código compila sem problemas, porém o SQL que é gerado está errado

Como podem reparar a estrutura das subqueries não é montada de maneira correta. A tabela da segunda subquey é colocada junto com a primeira subquery.
Alguem tem alguma dica do que estou fazendo de errado?

1 curtida