5

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?

Syngularity
  • 795
  • 3
  • 17
  • 42
  • 1
    you should post your edit as an answer; function should be registered if used in `select`, and also don't forget to add the metadata_builder_contributor property also in test scope config - I did the mistake of forgetting about it ;) – Kamil Jul 19 '22 at 22:18
  • I ran into a similar problem and filed a bug here: https://hibernate.atlassian.net/browse/HHH-16308 – Archie Mar 14 '23 at 22:33

1 Answers1

0

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?

Syngularity
  • 795
  • 3
  • 17
  • 42