'Using custom function call in CriteriaQuery multiselect cause a null pointer exception

I have a spring boot based application with hibernate-types included to properly map Postgres array to JPA entities. It works fine, but I run into an issue when I would like to create a CriteriaQuery.

The sql schema is the following:

create table if not exists my_values
    (
        id          bigserial,
        external_id varchar(255),
        ts_values   double precision[]
    );

Also, I already have a perfectly working JPA Entity for this table, and I would like to create the following type-safe criteria query with JPA:

select external_id, cardinality(ts_values)
from my_values
where external_id = 'my_extermal_id'

Writing the query with JPA criteria API was pretty easy, but whenever I try to run the query it produces a null pointer exception.

The java code so far:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<MyData> query = cb.createQuery(MyData.class);
Root<MyDataEntity> root = query.from(MyDataEntity.class);

query.multiselect(
    root.get(MyDataEntity_.externalId),
    cb.function("cardinality", Integer.class, root.get(MyDataEntity_.values))
);

query.where(cb.equal(root.get(MyDataEntity_.externalId), id));

return em.createQuery(query).getSingleResult();

As I mentioned the entity implementation works fine, I could save and read data perfectly, MyData class has the appropriate constructor as well. When I replace the cb.function call by simply selecting the whole array instead it works fine too, I suspect having a function in a multi-select causes a problem.

java.lang.NullPointerException: Cannot invoke "org.hibernate.type.Type.getColumnSpan(org.hibernate.engine.spi.Mapping)" because "types[i]" is null at org.hibernate.hql.internal.NameGenerator.generateColumnNames(NameGenerator.java:27) at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.generateColumnNames(SessionFactoryHelper.java:434)

I tried to add alias and explicit type declaration to the function expression .as(Integer.class).alias("value") but that does not solve the problem, I got the same exception. I have no idea what I'm doing wrong, is it even possible to do?

Solution:

You should create a MetadataBuilderContributor implementation, that you set hibernate.metadata_builder_contributor in your properties

For more detail: How to register non-standarized SQL functions manually in Spring Boot application?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source