我有一个称为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], ...);
    }
    

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

    09-10 01:40
    查看更多