Skip to content
Advertisement

Spring repository: HQL using constructor doens’t parse NULL values

I’ve a Spring Repository with this HQL query:

    @Transactional(readOnly = true)
    @Query(value = "SELECT new mypackage.PupillaryDistanceDTO(e.pupillaryDistanceFarTot,e.pupillaryDistanceFarDx,e.pupillaryDistanceFarSx,null ,null,null,null,null,null,e.pupillaryDistanceNearTot,e.pupillaryDistanceNearDx,e.pupillaryDistanceNearSx) FROM EyeExamination e WHERE e.contact.id=:contactId ORDER BY e.id DESC")
    Page<PupillaryDistanceDTO> findLastPupillaryDistance(@Param("contactId") long contactId, Pageable pageable);

PupillaryDistanceDTO is a POJO annotated with @AllArgsConstructor(Lombok); unfortunately those null values I want to pass to the constructor are creating some troubles:

Caused by: java.lang.NullPointerException
    at org.hibernate.hql.internal.NameGenerator.generateColumnNames(NameGenerator.java:27) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.generateColumnNames(SessionFactoryHelper.java:434) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.ast.tree.SelectClause.initializeColumnNames(SelectClause.java:268) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.ast.tree.SelectClause.finishInitialization(SelectClause.java:258) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.ast.tree.SelectClause.initializeExplicitSelectClause(SelectClause.java:253) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.ast.HqlSqlWalker.useSelectClause(HqlSqlWalker.java:1026) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.ast.HqlSqlWalker.processQuery(HqlSqlWalker.java:794) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:689) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:325) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:273) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:276) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:192) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:144) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:113) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:73) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:162) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:604) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:716) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:113) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at jdk.internal.reflect.GeneratedMethodAccessor150.invoke(Unknown Source) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:564) ~[?:?]
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:362) ~[spring-orm-5.3.3.jar:5.3.3]
    at com.sun.proxy.$Proxy267.createQuery(Unknown Source) ~[?:?]
    at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:87) ~[spring-data-jpa-2.4.3.jar:2.4.3]
    at org.springframework.data.jpa.repository.query.SimpleJpaQuery.<init>(SimpleJpaQuery.java:63) ~[spring-data-jpa-2.4.3.jar:2.4.3]
    at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromMethodWithQueryString(JpaQueryFactory.java:76) ~[spring-data-jpa-2.4.3.jar:2.4.3]
    at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromQueryAnnotation(JpaQueryFactory.java:56) ~[spring-data-jpa-2.4.3.jar:2.4.3]
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:146) ~[spring-data-jpa-2.4.3.jar:2.4.3]
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:216) ~[spring-data-jpa-2.4.3.jar:2.4.3]
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:81) ~[spring-data-jpa-2.4.3.jar:2.4.3]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lookupQuery(QueryExecutorMethodInterceptor.java:100) ~[spring-data-commons-2.4.3.jar:2.4.3]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lambda$mapMethodsToQuery$1(QueryExecutorMethodInterceptor.java:93) ~[spring-data-commons-2.4.3.jar:2.4.3]
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195) ~[?:?]
    at java.util.Iterator.forEachRemaining(Iterator.java:133) ~[?:?]
    at java.util.Collections$UnmodifiableCollection$1.forEachRemaining(Collections.java:1056) ~[?:?]
    at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801) ~[?:?]
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[?:?]
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[?:?]
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) ~[?:?]
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:?]
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) ~[?:?]

Removing those null and replacing with some table’s columns, it works. Is there a way to tell Hibernate to interpret those null in the right way?

Advertisement

Answer

You could try to use nullif(1,1) to emulate the null, but it would be better to just create an appropriate constructor that doesn’t require passing nulls.

Advertisement