NullPointerException in generateColumnNames()

Getting null pointer exception when using function in in selection wen mapped to class

at org.hibernate.hql.internal.NameGenerator.generateColumnNames(NameGenerator.java:27) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.generateColumnNames(SessionFactoryHelper.java:434) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.hql.internal.ast.tree.SelectClause.initializeColumnNames(SelectClause.java:268) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.hql.internal.ast.tree.SelectClause.finishInitialization(SelectClause.java:258) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.hql.internal.ast.tree.SelectClause.initializeExplicitSelectClause(SelectClause.java:253) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.hql.internal.ast.HqlSqlWalker.useSelectClause(HqlSqlWalker.java:1028) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.hql.internal.ast.HqlSqlWalker.processQuery(HqlSqlWalker.java:796) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:694) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:330) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:278) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:276) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:192) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:144) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:113) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:73) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:162) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:613) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:725) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:788) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.query.criteria.internal.CriteriaQueryImpl$1.buildCompiledQuery(CriteriaQueryImpl.java:314) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.query.criteria.internal.compile.CriteriaCompiler.compile(CriteriaCompiler.java:165) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:751) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:23) ~[hibernate-core-5.4.31.Final.jar:5.4.31.Final]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_202]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_202]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_202]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_202]
	at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:314) ~[spring-orm-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at com.sun.proxy.$Proxy190.createQuery(Unknown Source) ~[na:na]

I inspected the code and found for the type corresponding to my function always has its type as null in types.
On further inspection I found that If the function defined is not inside the SQLFuctionRegistery its return type will be null when called from

MethodNode.dialectFunction(AST experList);

is there any work around for it other that taking the results as an array of object and then constructing the Required instance from there

Not sure how your query looks like, but you could try to cast the function like this cast(function('my_function', ..) as string)

I have casted the function, in the query plan the type for the function is String, I have confirmed this with the AST tree

Did you solve the issue? I am having a similar problem with a query like

CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
CriteriaQuery<ResultDto> query = builder.createQuery(ResultDto.class);

Root<Building> building = query.from(Building.class);
Join<Building, Visit> visit = building.join("visits", JoinType.LEFT);

query.select(builder.construct(
    ResultDto.class,
    building.get("name"),
    builder.function("STRING_AGG", String.class, visit.get("visitorName"), builder.literal(", ")),
    builder.count(visit.get("id"))
));

query.groupBy(building.get("id"));

final TypedQuery<ResultDto> typedQuery = getEntityManager().createQuery(query);

The MethodNode for the function string_agg is returning null with .getDataType(). So the resulting stacktrace and NPE is the same. I cannot find a solution or workaround to this.

Try to force the cast by using e.g. builder.function("STRING_AGG", Integer.class, visit.get("visitorName"), builder.literal(", ")).as(String.class)

@anddero No I have not, Im using result set now due to time constrains

@beikov This does not help. It turns out Postgresql95Dialect does not have many methods registered, that are actually present in the equivalent version of the PostgreSQL language. I solved it by registering some functions in a custom dialect, example:

public class PmsDokumendidDialect extends PostgreSQL95Dialect {

  public PmsDokumendidDialect() {
    // Workaround, because "string_agg" function does not seem to be defined in the PostgreSQL dialect.
    registerFunction( "string_agg", new StandardSQLFunction("string_agg", StandardBasicTypes.STRING) );
  }

}

Registering the functions directly is always an option if you can. If you can’t, you have to cast the result somehow, but that won’t help you with custom user types. The original question was about string_agg though.

I think I’ll update my questions with code and the query later to get a better picture.
But I cant do this since the dialect is defined in spring configuration in my project.

@beikov I actually began with STRING_AGG for which the same solution worked (casting did not work). I later decided that ARRAY_AGG was more appropriate for my needs and changed it. I will update the above comment.

Are there any example projects out there where the functions can be used without registering them in a custom dialect?

Well, you can contribute the functions within an Integrator that is loaded via the Java ServiceLoader mechanism, but functions are dialect specific, so if you support multiple dialects, you will have to do some instanceof checks against the dialect to register the appropriate functions.