Hibernate 6.x breaks function validation on custom userType parameters

Hello,

I’m attempting to upgrade my application from Hibernate 5 to 6 and seem to be having issues with HQL queries using functions where a custom UserType is the parameter.

My entity has a field of type java.time.Duration, which is represented in the Postgres database as interval type. I’m using Hypersistence’s PostgreSQLIntervalType to do the conversion. The field in the entity is annotated with @Type(PostgreSQLIntervalType::class).
The query I’m doing is simplified as follows: SELECT max(entity.field) FROM Entity entity GROUP BY ....

This works fine in Hibernate 5, but fails in 6 with the following error:
Parameter 1 of function 'max()' has type 'COMPARABLE', but argument is of type 'java.time.Duration' mapped to 'UserTypeSqlTypeAdapter(io.hypersistence.utils.hibernate.type.interval.PostgreSQLIntervalType@40085ab3)

In a debugger I found out that since 6, AbstractSharedSessionContract#createSql calls the method interpretHql which eventually enters org.hibernate.query.sqm.produce.function.ArgumentTypesValidator#checkArgumentType which throws the error.
The interesting parameters to that method are:

type: COMPARABLE
code: 1111
sqlType: UserTypeSqlTypeAdapter(io.hypersistence.utils.hibernate.type.interval.PostgreSQLIntervalType@40085ab3)
javaType: java.time.Duration

I wasn’t able to find anything related online regarding this, which I’m confused about. I don’t think this problem should be very niche. I’m hoping you can help me out with this. I should be able to create a small reproduction project if needed.

Cheers,
Martin

This is a bug. Please create a bug ticket in our issue tracker.

The fix should be quite easy, simply add || isIntervalType( code ) to org.hibernate.type.descriptor.jdbc.JdbcType#isComparable. You are very welcome to create a PR with a fix for this.

Sure, will do! Thanks for the quick reply.

For now, I have created this JIRA issue, but I still have to provide a test case and the PR.
If there are any pointers to where the test-case would best fit, please let me know.

1 Like

Using the pointers I was given in the JIRA issue, I found another approach instead of making it work without using the Hypersistence library.

class Entity {
...
    @Column
    @JdbcType(CustomPostgreSQLIntervalSecondJdbcType::class)
    val duration: Duration,
...
}
...
class CustomPostgreSQLIntervalSecondJdbcType : PostgreSQLIntervalSecondJdbcType() {
    override fun isComparable() = true
}