我有一个名为X的Hibernate托管Java实体和一个本机SQL函数(myfunc),我从Hibernate SQL查询中调用这些函数:
SQLQuery q = hibernateSession.createSQLQuery(
"SELECT *, myfunc(:param) as result from X_table_name"
);
我想要做的是将从此查询返回的所有内容映射到一个名为Y的类(不一定由Hibernate管理).Y应包含X中的所有属性/字段以及{result
返回的myfunc
1}},例如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中相应字段所期望的类型。例如,类型为enum的日期中的字段和Date不能直接从SQL查询返回的Map映射(他们是字符串)。处理这种情况的适当方法是什么?
答案 0 :(得分:16)
请参阅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], ...);
}
这可以避免反射,让你控制一切。
答案 1 :(得分:7)
易。将行转换为Map<String, Object>
:
final org.hibernate.Query q = session.createSQLQuery(sql);
q.setParameter("geo", geo);
q.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
final List<Map<String, Object>> src = q.list();
final List<VideoEntry> results = new ArrayList<VideoEntry>(src.size());
for (final Map<String, Object> map:src) {
final VideoEntry entry = new VideoEntry();
BeanUtils.populate(entry, map);
results.add(entry);
}
答案 2 :(得分:0)
首先你需要在hibernate配置xml文件中声明这样的实体:..... class =&#34;实体的路径&#34;
或者您可以在进行查询之前以编程方式执行相同的操作。