17

我有一个名为 X 的 Hibernate 托管 Java 实体和一个从 Hibernate SQL 查询中调用的本机 SQL 函数 (myfunc):

SQLQuery q = hibernateSession.createSQLQuery(
                     "SELECT *, myfunc(:param) as result from X_table_name"
             );

我想要做的是将从此查询返回的所有内容映射到一个名为 Y 的类(不一定由 Hibernate 管理)。 Y 应该包含来自 X 的所有属性/字段加上result返回的myfunc,例如 Y 可以扩展类 X 并添加一个“结果”字段。

我试过的:

  1. 我试过使用q.addEntity(Y.class),但这失败了: org.hibernate.MappingException: Unknown entity com.mycompany.Y
  2. q.setResultTransformer(Transformers.aliasToBean(Y.class));但这失败了:org.hibernate.PropertyNotFoundException: Could not find setter for some_property。X 有一个someProperty用适当的 getter 和 setter 调用的字段,但在这种情况下,Hibernate 似乎没有将列名 (some_property) 映射到正确的字段名。
  3. q.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);返回一个 Map,但值并不总是 X 中相应字段所期望的类型。例如,X 中类型为 enum 和 Date 的字段不能直接从 SQL 查询返回的 Map 映射(它们是字符串)。

处理这种情况的适当方法是什么?

4

3 回答 3

16

请参阅文档中有关 SQL 查询的章节

您可以使用该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], ...);
}

这样可以避免反射,并让您控制一切。

于 2012-08-07T22:03:23.233 回答
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);
}
于 2016-03-21T02:40:29.800 回答
0

首先,您需要在休眠配置 xml 文件中声明实体,如下所示:..... class="path to your entity"

或者,您可以在进行查询之前以编程方式执行相同的操作。

于 2015-03-01T08:56:34.240 回答