2014-10-07 8 views
7

Attualmente sto lavorando su un progetto che utilizza queryDSL e ibernazione in cui richiede un letterale selezionato. Seguendo gli esempi pubblicati here ho:Come selezionare valori letterali in QueryDSL

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

dove la classe Foo ha un costruttore che accetta un BigDecimal. Quando si esegue questo in prova, ottengo

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) 

cambiare questo a:

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

produce una stacktrace diversa:

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) 

Ho provato a cambiare il costruttore della classe Foo ad accettare Integer e la query modificata per utilizzare Intero anche per motivi di test e ha prodotto la query corretta:

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

utilizza NumberTemplate il modo corretto per selezionare i valori letterali BigDecimal? Il documento NumberTemplate specifica T che estende il numero e confrontabile ma non riesce su tipi non interi. Come seleziono correttamente costanti/letterali in querydsl?

+0

Ho avuto la stessa eccezione e anche risolto utilizzando NumberTemplate.create (Long.class, "1") al posto di Expressions.constant (1L) – Stephane

+0

La mia dichiarazione completa: 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())); \t \t Lista resultList = query.distinct(). Lista (qRolloutMeta); – Stephane

+0

Ciao Stephane, posso confermare che questo funziona davvero per i lavori di tipo intero o lungo ma non per BigDecimal (esempio sul terzo blocco di codice dell'OP) – geneqew

risposta

0

Ho avuto un problema simile e ho chiesto a uno sviluppatore di QueryDSL di parlarne. la risposta è stata: "È un bug in Hibernate, non possiamo/non lo aggiusteremo". Potrebbe essere necessario utilizzare qualcos'altro oltre ad un Expressions.constant per farlo funzionare.

Nel mio codice, funziona con un codice simile a questo:

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