636 words

Issue #128 - Weird issue with variable naming

BugVersion: Priority: NormalStatus: FixedReplies: 4
#1
2012-01-17 07:32

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;
  }
}
}
quasado
quasado's picture
Joined on 2011-04-30
User Post #80
#2
2012-01-17 07:36

oh and we re-use a join setup in our filter for the order by clause as well not sure if that makes the difference though I am doing that in the demo code as well without success of replication..

quasado
quasado's picture
Joined on 2011-04-30
User Post #81
#3
2012-01-17 08:05

Please post the query string with double use of $1.

What is the purpose of the test case that you posted? Is it the same query? similar query?

Can you post the code that build the problematic query?

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
support
support's picture
Joined on 2010-05-03
User Post #862
#4
2012-01-18 05:56

Hi,

I finally found a way to replicate it and I found out why / when it happens. Take this code:

package com.test;
 
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
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();
 
  final CriteriaBuilder cb = em.getCriteriaBuilder();
  final CriteriaQuery<Tuple> cq = cb.createTupleQuery();
  final Root<?> from = cq.from(MyEntity.class);
 
  final Join<?, ?> join = from.join("embedded", JoinType.LEFT);
 
  // COMMENT THIS OUT AND IT WORKS OK
  from.get("name").toString();
 
  System.out.println(cq.toString());
 
  em.close();
  emf.close();
}
 
@Entity
public static final class MyEntity
{
  public MyEmbedded embedded = new MyEmbedded();
  public String name = null;
 
  public MyEntity()
  {
   name = "TEST";
  }
}
 
@Embeddable
public static final class MyEmbedded
{
  public String name = "TEST";
 
  public String getName()
  {
   return name;
  }
 
  public void setName(String name)
  {
   this.name = name;
  }
}
}

When using the toString() function of the path it turns out the variable naming goes wrong ($1 is twice). Comment this line from.get("name").toString(); out and everything works as expected ($1 and $2 are used). Now this is critical for us because we need to full path string for query replacing stuff later on as well as this happens during debugging because when you check the value of a path (which calls toString()), your whole query goes wrong after debugging!!

thanks for a fast fix,

Alex

quasado
quasado's picture
Joined on 2011-04-30
User Post #83
#5
2012-01-18 06:19

Yes, toString invocation should not affect. Build 2.3.6_08 fixes it.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
support
support's picture
Joined on 2010-05-03
User Post #865

Post Reply

Please read carefully the posting instructions - before posting to the ObjectDB website.

  • You may have to disable pop up blocking in order to use the toolbar (e.g. in Chrome).
  • Use ctrl + right click to open the browser context menu in the editing area (e.g. for using a browser spell checker).
  • To insert formatted lines (e.g. Java code, stack trace) - select a style in the toolbar and then insert the text in the new created block.
  • Avoid overflow of published source code examples by breaking long lines.
  • You may mark in paragraph code words (e.g. class names) with the code style (can be applied by ctrl + D).
  • Long stack traces (> 50 lines) and complex source examples (> 100 lines) should be posted as attachments.
Attachments:
Maximum file size: 32 MB
Cancel