[英]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: 我尝试过的:
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
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. someProperty
的字段,带有相应的getter和setter,但在这种情况下,似乎Hibernate不会将列名(some_property)映射到正确的字段名。 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). 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.