The following code doesn't respect the logical "or" correctly. Instead of returns all 2 datasets it returns only this one, which matches the first predicate in the or. BUT: this happens only, if the field for the "or" is the first one defined as @Id.
public class OrTest { @Entity static class Data { Data(String a, String b) { this.a = a; this.b = b; } @Id String a; @Id String b; public Data() { } } public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("or_test.odb"); EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); em.persist(new Data("1", "x")); em.persist(new Data("12", "y")); em.getTransaction().commit(); CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaQuery<Data> query = builder.createQuery(Data.class); Root<Data> root = query.from(Data.class); query.select(root); query.where((builder.or( builder.equal(root.get("a"), "1"), builder.like(root.get("a"), "1%") ))); System.out.println(em.createQuery(query).getResultList().size()); } }
This outputs instead of 2 only:
1
If you change the order:
@Id String b; @Id String a;
the code outputs:
2
What is wrong? I'm afraid that the order of @Id changes query behaviour to wrong.