Как выбрать литералы в QueryDSL

В настоящее время я работаю над проектом, который использует queryDSL и спящий режим, в котором требуется литерал выбора. Следуя примерам, опубликованным здесь, у меня есть:

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

где класс Foo имеет конструктор, который принимает BigDecimal. При запуске этого в тесте я получаю

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)

изменив это на:

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

создает другую трассировку стека:

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)

Я попытался изменить конструктор класса Foo, чтобы он принимал целое число, и запрос, измененный для использования целого числа, также ради тестирования, и он действительно выдал правильный запрос:

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

Является ли использование NumberTemplate правильным способом выбора литералов BigDecimal? Документы NumberTemplate указывают T, расширяющий Number и Comparable, но не работают с типами, отличными от Integer. Как правильно выбрать константы/литералы в querydsl?


person geneqew    schedule 07.10.2014    source источник
comment
У меня было такое же исключение, и я также решил его, используя NumberTemplate.create(Long.class, 1) вместо Expressions.constant(1L)   -  person Stephane    schedule 28.10.2014
comment
Мое полное заявление: 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‹RolloutMeta› resultList = query.distinct().list(qRolloutMeta);   -  person Stephane    schedule 28.10.2014
comment
Привет, Стефан, я могу подтвердить, что это действительно работает для целочисленного или длинного типа, но не для BigDecimal (пример в 3-м блоке кода OP)   -  person geneqew    schedule 28.10.2014
comment
Привет, мне интересно, почему мы не можем использовать форму Expressions.constant()...   -  person Stephane    schedule 28.10.2014


Ответы (1)


У меня была похожая проблема, и я спросил об этом разработчика QueryDSL. ответ был таким: "Это ошибка в Hibernate, мы не можем/не будем ее исправлять". Возможно, вам придется использовать что-то еще, кроме Expressions.constant, чтобы заставить его работать.

В моем коде он работает с кодом, подобным этому:

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

person Guillaume F.    schedule 17.11.2015