简体   繁体   English

如何使用Hibernate将SQL查询的结果最佳映射到非实体Java对象?

[英]How to best map results from an SQL query to a non-entity Java object using Hibernate?

I have a Hibernate managed Java entity called X and a native SQL function (myfunc) that I call from a Hibernate SQL query along these lines: 我有一个名为X的Hibernate托管Java实体和一个本机SQL函数(myfunc),我从Hibernate SQL查询中调用这些函数:

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

What I want to do is to map the everything returned from this query to a class (not necessarily managed by Hibernate) called Y. Y should contain all properties/fields from X plus the result returned by myfunc , eg Y could extend class X and add a "result" field. 我想要做的是将从此查询返回的所有内容映射到一个名为Y的类(不一定由Hibernate管理).Y应包含X中的所有属性/字段以及myfunc返回的result ,例如Y可以扩展类X和添加“结果”字段。

What I've tried: 我尝试过的:

  1. I've tried using q.addEntity(Y.class) but this fails with: org.hibernate.MappingException: Unknown entity com.mycompany.Y 我尝试过使用q.addEntity(Y.class)但是失败了: org.hibernate.MappingException: Unknown entity com.mycompany.Y
  2. q.setResultTransformer(Transformers.aliasToBean(Y.class)); but this fails with: org.hibernate.PropertyNotFoundException: Could not find setter for some_property . 但是这失败了: org.hibernate.PropertyNotFoundException: Could not find setter for some_property X has a field called someProperty with the appropriate getter and setter but in this case it doesn't seem like Hibernate maps the column name (some_property) to the correct field name. X有一个名为someProperty的字段,带有相应的getter和setter,但在这种情况下,似乎Hibernate不会将列名(some_property)映射到正确的字段名。
  3. q.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP); returns a Map but the values are not always of the type expected by the corresponding field in X. For example fields in X of type enum and Date cannot be mapped directly from the Map returned by the SQL query (where they are Strings). 返回一个Map,但值并不总是X中相应字段所期望的类型。例如,类型为enum和Date的X字段不能直接映射到SQL查询返回的Map(它们是字符串)。

What's the appropriate way to deal with this situation? 处理这种情况的适当方法是什么?

See the chapter of the documentation about SQL queries . 请参阅有关SQL查询的文档一章

You can use the addScalar() method to specify which type Hibernat should use for a given column. 您可以使用addScalar()方法指定Hibernat应该为给定列使用的类型。

And you can use aliases to map the results with the bean properties: 您可以使用别名将结果映射到bean属性:

select t.some_property as someProperty, ..., myfunc(:param) as result from X_table_name t

Or, (and although it require some lines of code, it's my preferred solution), you can simply do the mapping yourself: 或者,(虽然它需要一些代码行,这是我的首选解决方案),您可以自己简单地进行映射:

List<Object[]> rows = query.list();
for (Object[] row : rows) {
    Foo foo = new Foo((Long) row[0], (String) row[1], ...);
}

This avoids reflection, and lets you control everything. 这可以避免反射,并让您控制一切。

Easy. 简单。 Cast the rows to Map<String, Object> : 将行转换为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);
}

First of all you need to declare the entity in the hibernate configuration xml file something like this: ..... class="path to your entity" 首先,你需要在hibernate配置xml文件中声明这样的实体:..... class =“your entity to your entity”

Or you can do the same thing programatically before you make the query. 或者,您可以在进行查询之前以编程方式执行相同的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM