hi,
We've hit again against troubles with the variable naming when trying to get the query string with CriteriaQuery.toString(). I've tried three hours to replicate it without success, all I can say is that we do a LEFT JOIN on an embedded property as well as ordering is involved in selection and order by. Removing the addition of order stuff solves the issue of double naming though doesn't help us without ordering. The issue is that the name of the root variable is $1 as well as the name of our left join variable becomes $1. We're also adding a custom function expression in where clause though however as said, cannot replicate it in a demo, however here's my code I was trying to replicate it which is similiar to what we do. We'd really need this fixed urgently, we cannot work with order by right now :((
package com.test; import java.util.HashMap; import java.util.Map; import javax.persistence.CascadeType; import javax.persistence.Embeddable; import javax.persistence.Entity; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.OneToMany; import javax.persistence.Persistence; import javax.persistence.Tuple; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Join; import javax.persistence.criteria.JoinType; import javax.persistence.criteria.Root; public final class F329 { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("objectdb:$objectdb/db/test_F329.tmp;drop"); EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); for (int i = 0; i < 1000; ++i) { MyEntity entity = null; if (i % 2 == 0) { entity = new MyEntity(new MyMapEntity("Name-" + Integer.toString(i))); } else { entity = new MyEntity(); } em.persist(entity); } em.getTransaction().commit(); final CriteriaBuilder cb = em.getCriteriaBuilder(); final CriteriaQuery<Tuple> cq = cb.createQuery(Tuple.class); final Root<?> from = cq.from(MyEntity.class); final Join<?, ?> join2 = from.join("embedded", JoinType.LEFT); final Join<?, ?> join = from.join("map", JoinType.LEFT); cq.multiselect(from, join2.get("name")); cq.where(cb.equal(join2.get("name"), cb.literal("TEST"))); cq.orderBy(cb.asc(join2.get("name"))); System.out.println(cq.toString()); System.out.println(em.createQuery(cq).getResultList()); em.close(); emf.close(); } @Entity public static final class MyEntity { @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) public Map<String, MyMapEntity> map = new HashMap<String, MyMapEntity>(); public MyEmbedded embedded = new MyEmbedded(); public MyEntity() { } public MyEntity(MyMapEntity... mapEntities) { for (MyMapEntity me : mapEntities) { map.put(me.name123, me); } } } @Embeddable public static final class MyEmbedded { public String name = "TEST"; public String getName() { return name; } public void setName(String name) { this.name = name; } } @Entity public static final class MyMapEntity { public String name123; public MyMapEntity() { } public MyMapEntity(String name123) { this.name123 = name123; } } }