6

Im currently working on a project that uses queryDSL and hibernate wherein it requires a select literal. Following the examples posted here i have:

createQuery().
   from(path()).
      where(specification().getPredicate()).
          list(
   ConstructorExpression.create(Foo.class, Expressions.constant(BigDecimal.ONE)));

where Foo class has a constructor which accepts a BigDecimal. When running this in test, i get

org.hibernate.QueryException: Parameters are only supported in SELECT clauses when used as part of a INSERT INTO DML statement
    at org.hibernate.hql.internal.ast.tree.SelectClause.initializeExplicitSelectClause(SelectClause.java:146)

changing this to:

createQuery()
   .from(path()).
       where(specification().getPredicate())
           .list(
ConstructorExpression.create(Foo.class, NumberTemplate.create(BigDecimal.class, "1.0")));

produces a different stacktrace:

java.lang.IllegalArgumentException: argument type mismatch
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at com.mysema.query.types.ConstructorExpression.newInstance(ConstructorExpression.java:133)
    at com.mysema.query.jpa.FactoryExpressionTransformer.transformTuple(FactoryExpressionTransformer.java:50)

I tried changing the Foo class constructor to accept Integer and the query modified to use Integer as well for the sake of testing and it did produces the correct query:

createQuery()
   .from(path()).
      where(specification().getPredicate())
         .list(ConstructorExpression.create(LevelBoundary.class, NumberTemplate.create(Integer.class, "1")));

Is using NumberTemplate the correct way to select BigDecimal literals? The NumberTemplate docs specifies T extending Number and Comparable but fails on non Integer types. How do i properly select constants/literals in querydsl?

Community
  • 1
  • 1
geneqew
  • 2,401
  • 5
  • 33
  • 48
  • I had the same exception and also solved it by using NumberTemplate.create(Long.class, "1") instead of Expressions.constant(1L) – Stephane Oct 28 '14 at 06:27
  • My full statement: QRolloutMeta qRolloutMeta = new QRolloutMeta(qRollout, NumberTemplate.create(Long.class, qBTS.count().toString()), NumberTemplate.create(Integer.class, btsNbPlanned.toString()), NumberTemplate.create(Integer.class, btsNbCompleted.toString()), NumberTemplate.create(Integer.class, btsPercentage.toString())); List resultList = query.distinct().list(qRolloutMeta); – Stephane Oct 28 '14 at 06:52
  • Hi Stephane, I can confirm that this indeed works for integer or Long type works but not for BigDecimal (sample on the 3rd block of code of the OP) – geneqew Oct 28 '14 at 11:59
  • 1
    Hi, I wonder why we cannot use the Expressions.constant() form... – Stephane Oct 28 '14 at 12:11

1 Answers1

0

I've had a similar problem, and asked a developer of QueryDSL about it. the answer was : "It's a bug in Hibernate, we can't / won't fix it". You may have to use something else than an Expressions.constant to get it to work.

In my code, it works with a code similar to this :

ConstructorExpression.create(LevelBoundary.class, Expressions.stringTemplate("'1'")

Guillaume F.
  • 5,905
  • 2
  • 31
  • 59