There is no easy way, but I think you don’t need registerHibernateType anymore. As for registerFunction, I’d suggest you rather introduce a org.hibernate.boot.model.FunctionContributor:
public class MyFunctionContributor imlements org.hibernate.boot.model.FunctionContributor {
public void contributeFunctions(FunctionContributions functionContributions) {
functionContributions.getFunctionRegistry().registerAlternateKey("group_concat", "listagg");
functionContributions.getFunctionRegistry().registerPattern("match_against", "match (?1) against (?2 in boolean mode)", functionContributions.getTypeConfiguration().getBasicTypeRegistry().resolve(StandardBasicTypes.DOUBLE));
}
}
Note that you also need a file META-INF/services/org.hibernate.boot.model.FunctionContributor that contains the fully qualified class name of MyFunctionContributor.
I upgraded Hibernate from 5.6 to 6.2 and I want to use FunctionContributor to use custom functions in my Hibernate queries. and I use register method like that:
@Override
public void contributeFunctions(FunctionContributions functionContributions) {
functionContributions.getFunctionRegistry().register("string_agg",
new StandardSQLFunction("string_agg", StandardBasicTypes.STRING));
}
and I created the file META-INF/services/org.hibernate.boot.model.FunctionContributor. This file contains fully qualified class name. But somehow my custom function cannot be recognized. Can you help me out to understand what is wrong?
Hi @beikov,
I have following custom dialect config in hibernate 5
public Oracle12cCustomDialect() {
super();
this.registerHibernateType(2003, DecimalArrayType.class.getName());
}
However, when I upgrade to hibernate 6 along with spring boot 3. I get the following error when I remove the above code.
java.lang.NullPointerException: Cannot invoke "String.hashCode()" because "this.typeName" is null
at org.hibernate.dialect.OracleArrayJdbcType.hashCode(OracleArrayJdbcType.java:202)
at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1694)
at org.hibernate.type.BasicTypeRegistry.resolve(BasicTypeRegistry.java:192)
at org.hibernate.type.BasicTypeRegistry.resolve(BasicTypeRegistry.java:160)
at org.hibernate.sql.results.jdbc.internal.ResultSetAccess.resolveType(ResultSetAccess.java:146)
Can you help me resolve this ?
It looks like I can’t use registerHibernateType anymore and without that this error occurs.
I checked doc and also dug deep into codebase and it looks like a bug in hibernate.
For the column type MDSYS.SDO_ORDINATE_ARRAY which my query is returning, typeName field is being null from org.hibernate.type.descriptor.jdbc.JdbcType.
Check the below snapshot from my debug session.
And due to this reason I am getting following error
java.lang.NullPointerException: Cannot invoke "String.hashCode()" because "this.typeName" is null
at org.hibernate.dialect.OracleArrayJdbcType.hashCode(OracleArrayJdbcType.java:202)
at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1694)
at org.hibernate.type.BasicTypeRegistry.resolve(BasicTypeRegistry.java:192)
at org.hibernate.type.BasicTypeRegistry.resolve(BasicTypeRegistry.java:160)
at org.hibernate.sql.results.jdbc.internal.ResultSetAccess.resolveType(ResultSetAccess.java:146)
If it’s a bug as I suspect it is, let me know where can I raise this bug issue ?
Thanks in advance !!
So you are running a native query that returns an Oracle “array”, though it seems SDO_ORDINATE_ARRAY is rather a spatial type.
I guess we are simply missing a translation from that type to the SqlTypes constants in resolveSqlTypeDescriptor, similar to what we already do for MDSYS.SDO_GEOMETRY in OracleDialect#resolveSqlTypeDescriptor. Can you explain to me what this SDO_ORDINATE_ARRAY represents? How was this deserialized before? As Geometry?
Please create an issue in the issue tracker(https://hibernate.atlassian.net) for this feature request. It should be easy to support, but if you need a solution now, you’ll have to override the resolveSqlTypeDescriptor of your custom dialect, something like this: