The product I’m upgrading from Hibernate 5 to Hibernate 6 previously made use of hibernate Dialects to take a convert_tz(…) call and translate it accordingly for various DBs (MariaDB, PostgreSQL etc…).
An example of the call:
convert_tz(entity.timestamp, '+00:00', '-04:00', -240, 'UTC', 'America/Anguilla'
The initial HQL query this is within, is generated by some impenetrable code that I’d like to avoid changing at all costs.
The given custom Dialect can then take it and convert it into something friendly for the current DB, see some examples below to see how flexible we need it to be. All of the potentially required data is stored in the initial call, and it’s reorganized accordingly.
MariaDB : convert_tz(entity.timestamp, '+00:00', '-04:00')
PostgreSQL : entity.timestamp AT time zone 'UTC' AT time zone 'America/Anguilla'
The Hibernate 5 way of defining this function in a dialect is no longer supported, it does not compile. (neither of the functions seem to exist anymore)
Here’s the Hibernate 5 way we succesfully had this working with which no longer compiles as of Hibernate 6:
public class CustomMariaDBDialect5 extends MariaDBDialect{
public CustomMariaDBDialect5 () {
registerColumnType( Types.TIMESTAMP, "datetime" );
super.registerFunction("convert_tz", new SQLFunctionTemplate(DateType.INSTANCE, "convert_tz(?1, ?2, ?3) "));
}
And here’s my naive attempt to upgrade this to Hibernate 6
public class CustomMariaDBDialect6 extends MariaDBDialect {
public CustomMariaDBDialect6() {
super();
}
@Override
public void contributeFunctions(FunctionContributions functionContributions) {
super.contributeFunctions(functionContributions);
functionContributions.getFunctionRegistry().registerPattern("convert_tz",
"convert_tz(?1, ?2, ?3) ", functionContributions.getTypeConfiguration().getBasicTypeRegistry().resolve(StandardBasicTypes.DATE));
}
@Override
protected String columnType(int sqlTypeCode) {
if(sqlTypeCode == Types.TIMESTAMP){
return "datetime";
}else{
return super.columnType(sqlTypeCode);
}
}
}
Via debug I can see that contributeFunctions is being called, and when I run my program I get the following error:
org.hibernate.query.sqm.produce.function.FunctionArgumentException: Function convert_tz() has 3 parameters, but 6 arguments given
My initial concern was that the dialect wasn’t being used at all (as then it would be calling directly to the MariaDB convert_tz call which indeed has 3 arguments), but Following these instructions, I registered this as a FunctionContributor, If I alter the dialect pattern by adding another parameter “convert_tz(?1, ?2, ?3, ?4)” the error then changes to say ‘4 parameters’ thus I am certain that the dialect and function are being correctly loaded.
So it seems that the new hibernate 6 way of registering functions is more strict about parameter count. Is it possible that our approach here is simply not supported anymore?