我有一个称为X的Hibernate托管Java实体和一个 native SQL函数(myfunc),我可以从Hibernate SQL查询中按以下方式进行调用:
SQLQuery q = hibernateSession.createSQLQuery(
"SELECT *, myfunc(:param) as result from X_table_name"
);
我想做的就是将这个查询返回的所有内容映射到一个名为Y的类(不一定由Hibernate管理)。Y应该包含X的所有属性/字段以及
result
返回的myfunc
,例如Y可以扩展X类并添加一个“结果”字段。我试过的
q.addEntity(Y.class)
,但这失败了:org.hibernate.MappingException: Unknown entity com.mycompany.Y
q.setResultTransformer(Transformers.aliasToBean(Y.class));
,但是失败:org.hibernate.PropertyNotFoundException: Could not find setter for some_property
。 X有一个名为someProperty
的字段,带有适当的getter和setter,但是在这种情况下,Hibernate似乎不将列名(some_property)映射到正确的字段名。 q.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
返回一个Map,但是值并不总是X中相应字段所期望的类型。例如,不能直接从SQL查询返回的Map中映射enum和Date类型的X中的字段(它们是字符串) 。 处理这种情况的合适方法是什么?
最佳答案
参见chapter of the documentation about SQL queries。
您可以使用addScalar()
方法来指定Hibernat应为给定列使用哪种类型。
您可以使用别名将结果与bean属性映射:
select t.some_property as someProperty, ..., myfunc(:param) as result from X_table_name t
或者,(尽管它需要一些代码行,但这是我的首选解决方案),您可以自己完成映射:
List<Object[]> rows = query.list();
for (Object[] row : rows) {
Foo foo = new Foo((Long) row[0], (String) row[1], ...);
}
这样可以避免反射,并让您控制一切。