acheron55
acheron55

Reputation: 5619

Hibernate Custom SQL Enum transformation fails

There are similar questions here but none of them worked in my case. I have a custom SQL which returns 2 columns: one string, one number. And string column is always a full uppercase ENUM name. I want to feed this result set into my custom bean which has the said enum.

Following the answer here for Hibernate 5.X, code is below

    Properties params = new Properties();
    params.put("enumClass", "MyEnumClass");
    params.put("useNamed", true);
    Type myEnumType = new TypeLocatorImpl(new TypeResolver()).custom(MyEnumClass.class, params);

    final Query query = getCurrentSession().createSQLQuery(MY_CUSTOM_SQL)
            .addScalar("col1", myEnumType)
            .addScalar("col2", StandardBasicTypes.INTEGER)
            .setLong("someSqlVar", someVal)
            .setResultTransformer(Transformers.aliasToBean(MyCustomBean.class));

    return query.list();

This code does not even execute query.list() method, it fails at this line:

Type myEnumType = new TypeLocatorImpl(new TypeResolver()).custom(MyEnumClass.class, params);

Exception trace:

Caused by: org.hibernate.MappingException: Unable to instantiate custom type: com.example.MyEnumClass
...
Caused by: java.lang.InstantiationException: com.example.MyEnumClass
...
Caused by: java.lang.NoSuchMethodException: com.example.MyEnumClass.<init>()
at java.lang.Class.getConstructor0(Class.java:3082) ~[?:1.8.0_60]
at java.lang.Class.newInstance(Class.java:412) ~[?:1.8.0_60]
at org.hibernate.type.TypeFactory.custom(TypeFactory.java:202) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.type.TypeFactory.custom(TypeFactory.java:193) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.internal.TypeLocatorImpl.custom(TypeLocatorImpl.java:144) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
...

So hibernate is trying to call MyEnumClass.class.newInstance() and failing. It does not even check for properties I passed. Using Hibernate 5.1.0.Final, am I not supposed to use custom type this way?

Upvotes: 1

Views: 2189

Answers (1)

acheron55
acheron55

Reputation: 5619

I found a way to do it:

Properties params = new Properties();
params.put("enumClass", MyEnumClass.class.getName());
params.put("useNamed", true);

EnumType enumType = new EnumType();
enumType.setParameterValues(params);
CustomType customType = new CustomType(enumType);

final Query query = getCurrentSession().createSQLQuery(MY_CUSTOM_SQL)
   .addScalar("col1", customType)
   .addScalar("col2", StandardBasicTypes.INTEGER)
   .setLong("someSqlVar", someVal)
   .setResultTransformer(Transformers.aliasToBean(MyCustomBean.class));

return query.list();

Upvotes: 3

Related Questions