Hibernate Custom SQL 枚举转换失败
Hibernate Custom SQL Enum transformation fails
这里有类似的问题,但 none 对我的情况有效。我有一个自定义 SQL 其中 returns 2 列:一个字符串,一个数字。字符串列始终是完整的大写 ENUM 名称。我想将此结果集提供给具有上述枚举的自定义 bean。
根据 Hibernate 5.X 的答案 here,代码如下
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();
此代码甚至不执行 query.list() 方法,它在这一行失败:
Type myEnumType = new TypeLocatorImpl(new TypeResolver()).custom(MyEnumClass.class, params);
异常跟踪:
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]
...
所以 hibernate 正在尝试调用 MyEnumClass.class.newInstance()
但失败了。它甚至不检查我传递的属性。使用 Hibernate 5.1.0.Final,我不应该这样使用自定义类型吗?
我找到了一种方法:
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();
这里有类似的问题,但 none 对我的情况有效。我有一个自定义 SQL 其中 returns 2 列:一个字符串,一个数字。字符串列始终是完整的大写 ENUM 名称。我想将此结果集提供给具有上述枚举的自定义 bean。
根据 Hibernate 5.X 的答案 here,代码如下
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();
此代码甚至不执行 query.list() 方法,它在这一行失败:
Type myEnumType = new TypeLocatorImpl(new TypeResolver()).custom(MyEnumClass.class, params);
异常跟踪:
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]
...
所以 hibernate 正在尝试调用 MyEnumClass.class.newInstance()
但失败了。它甚至不检查我传递的属性。使用 Hibernate 5.1.0.Final,我不应该这样使用自定义类型吗?
我找到了一种方法:
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();