JPA-HIBERNATE : Eu entendi as conjuncoes e disjuncoes ? É isso mesmo?

Olá Pessoal!

Peguei umas apostilas de JPA e li alguns tutoriais na internet, mas estou ainda um pouco perdido com relação a disjunction e conjunction no JPA.

Pelo que eu entendi a conjuncao serve para agrupar condições com o “AND” do sql, já a disjuncao serve para agrupar condições com “OR”. Estou certo? O material que pesquisei me parece muito confuso.

Tentei entao fazer o criteria gerar queries com o seguinte padrao:

WHERE (condicao1 = valor1 AND condicao2 = valor2) or (condicao3=valor3 and condicao4=valor4)

Entretanto eu nao tive sucesso com minha implementação:

        EntityManager em = JPAUtil.getEntityManager();
	
	// Instanciar o BUILDER de criteria
	CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
	
	//Cria uma criteria query que trabalha com Conta
	CriteriaQuery<Conta> cquery = criteriaBuilder.createQuery(Conta.class);
	
	//Obter RAIZ da query que consulta da entidade CONTA
	Root<Conta> root = cquery.from(Conta.class);
	
	Path<String> titularPath = root.<String>get("titular");
	Path<Integer> idPath = root.<Integer>get("id");
	Path<String> numeroPath = root.<String>get("numero");
	Path<String> bancoPath = root.<String>get("banco");

	Predicate titularIgual = criteriaBuilder.like(titularPath, "M%");
	Predicate idIgual = criteriaBuilder.equal(idPath, 1);
	Predicate idDiferente = criteriaBuilder.equal(idPath, 500);		

	//Conjuncao1 seria (idDiferente AND titularIgual) ???
	Predicate conjuncao1 = criteriaBuilder.conjunction();
	conjuncao1 = criteriaBuilder.and(conjuncao1,idDiferente);
	conjuncao1 = criteriaBuilder.and(conjuncao1,titularIgual);
	
	//Conjunao2 seria (idIgual AND titularIgual) ???
	Predicate conjuncao2 = criteriaBuilder.conjunction();
	conjuncao2 = criteriaBuilder.and(conjuncao2,idIgual);
	conjuncao2 = criteriaBuilder.and(conjuncao2,titularIgual);
	
	//Se minha logica estiver correta entao a disjuncao das duas conjuncoes deveria ser
	// (idDiferente AND titularIgual) or (idIgual AND titularIgual) Não?
	Predicate disjuncao = criteriaBuilder.disjunction();
	disjuncao = criteriaBuilder.or(conjuncao1,conjuncao2);	
		
	
	cquery.where(disjuncao);
	TypedQuery<Conta> tQuery = em.createQuery(cquery);
	List<Conta> contas = tQuery.getResultList();

Eu nao entendi o fato do Hibernate ter gerado a consulta abaixo:
where
1=1
and conta0_.id=500
and (
conta0_.titular like ?
)
or 1=1
and conta0_.id=1
and (
conta0_.titular like ?
)

Você entendeu certo, mas tá utilizando a criteria api de forma errada.

O operador OR é o operador de disjunção, e o operador AND é o operador de conjunção.

isso OR aquilo é uma disjunção.
isso AND aquilo é uma conjunção.

Quando você faz criteriaBuilder.disjunction(), ele te retorna um predicado com uma disjunção vazia. O mesmo acontece para a chamada criteriaBuilder.conjunction(), só que com o AND. Uma disjunção vazia equivale a FALSE, enquanto uma conjunção vazia equivale a TRUE.

Faz um tempinho que eu não mexo com a Criteria API, mas acho que o que você quer fazer é o seguinte:

Predicate idDiferenteANDtitularIgual = criteriaBuilder.and(idDiferente, titularIgual);
Predicate idIgualANDtitularIgual = criteriaBuilder.and(idIgual, titularIgual);

Predicate disjuncaoDasDuasConjuncoesAnteriores = criteriaBuilder.or(idDiferenteANDtitularIgual, idIgualANDtitularIgual);

TypedQuery<Conta> tQuery = em.createQuery(cquery.where(disjuncaoDasDuasConjuncoesAnteriores ));
List<Conta> contas = tQuery.getResultList();

Sei que é meio antigo esse post, mas concordo com o usuário @lvbarbosa, e quero fazer um complemento ao que ele escreveu. Continue a utilizar o Criteria ao invés do JPQL, pois sua execução é um pouco mais rápida que o JPQL.