Hibernate 查询示例和预测
-
01-07-2019 - |
题
简而言之:hibernate不支持投影和查询示例?我找到了这个帖子:
代码是这样的:
User usr = new User();
usr.setCity = 'TEST';
getCurrentSession().createCriteria(User.class)
.setProjection( Projections.distinct( Projections.projectionList()
.add( Projections.property("name"), "name")
.add( Projections.property("city"), "city")))
.add( Example.create(usr))
就像另一位海报所说,生成的 sql 一直有一个 where 类引用 y0_=?而不是 this_.city.
我已经尝试了几种方法,并搜索了问题跟踪器,但没有发现任何相关内容。
我什至尝试使用 Projection alias 和 Transformers,但它不起作用:
User usr = new User();
usr.setCity = 'TEST';
getCurrentSession().createCriteria(User.class)
.setProjection( Projections.distinct( Projections.projectionList()
.add( Projections.property("name"), "name")
.add( Projections.property("city"), "city")))
.add( Example.create(usr)).setResultTransformer(Transformers.aliasToBean(User.class));
有人使用过投影和查询示例吗?
解决方案
我可以看看你的 User 类吗?这只是使用下面的限制。我不明白为什么限制实际上与示例有任何不同(尽管我认为示例中默认情况下会忽略空字段)。
getCurrentSession().createCriteria(User.class)
.setProjection( Projections.distinct( Projections.projectionList()
.add( Projections.property("name"), "name")
.add( Projections.property("city"), "city")))
.add( Restrictions.eq("city", "TEST")))
.setResultTransformer(Transformers.aliasToBean(User.class))
.list();
我从未使用过alaistToBean,但我刚刚读到过它。您也可以循环查看结果。
List<Object> rows = criteria.list();
for(Object r: rows){
Object[] row = (Object[]) r;
Type t = ((<Type>) row[0]);
}
如果有必要,您可以自己手动填充用户。
如果没有更多信息来诊断问题,就很难调查问题。
其他提示
当您有与对象属性同名的别名时,似乎会发生此问题。Hibernate 似乎选择了别名并在 sql 中使用它。我发现这个记录 这里 和 这里, ,我相信这是 Hibernate 中的一个错误,尽管我不确定 Hibernate 团队是否同意。
不管怎样,我找到了一个适合我的情况的简单解决方法。你的旅费可能会改变。详细信息如下,我尝试简化此示例的代码,因此我对任何错误或拼写错误表示歉意:
Criteria criteria = session.createCriteria(MyClass.class)
.setProjection(Projections.projectionList()
.add(Projections.property("sectionHeader"), "sectionHeader")
.add(Projections.property("subSectionHeader"), "subSectionHeader")
.add(Projections.property("sectionNumber"), "sectionNumber"))
.add(Restrictions.ilike("sectionHeader", sectionHeaderVar)) // <- Problem!
.setResultTransformer(Transformers.aliasToBean(MyDTO.class));
会产生这样的sql:
select
this_.SECTION_HEADER as y1_,
this_.SUB_SECTION_HEADER as y2_,
this_.SECTION_NUMBER as y3_,
from
MY_TABLE this_
where
( lower(y1_) like ? )
这导致了错误: java.sql.SQLException:ORA-00904:“Y1_”:不合法的识别符
但是,当我更改限制以使用“this”时,如下所示:
Criteria criteria = session.createCriteria(MyClass.class)
.setProjection(Projections.projectionList()
.add(Projections.property("sectionHeader"), "sectionHeader")
.add(Projections.property("subSectionHeader"), "subSectionHeader")
.add(Projections.property("sectionNumber"), "sectionNumber"))
.add(Restrictions.ilike("this.sectionHeader", sectionHeaderVar)) // <- Problem Solved!
.setResultTransformer(Transformers.aliasToBean(MyDTO.class));
它生成了以下 sql,我的问题得到了解决。
select
this_.SECTION_HEADER as y1_,
this_.SUB_SECTION_HEADER as y2_,
this_.SECTION_NUMBER as y3_,
from
MY_TABLE this_
where
( lower(this_.SECTION_HEADER) like ? )
就是这样!解决一个痛苦问题的非常简单的方法。我不知道此修复如何转化为示例查询问题,但它可能会让您更接近。
这里真正的问题是 hibernate 中存在一个错误,它在 where 子句中使用选择列表别名:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-817
以防万一有人来这里寻找答案,请查看票证。花了 5 年时间才修复,但理论上它会出现在下一个版本中,然后我怀疑你的问题就会消失。
我面临着类似的问题。我正在使用“按示例查询”,并且想按自定义字段对结果进行排序。在 SQL 中我会做类似的事情:
select pageNo, abs(pageNo - 434) as diff
from relA
where year = 2009
order by diff
没有 order-by 子句它也能正常工作。我得到的是
Criteria crit = getSession().createCriteria(Entity.class);
crit.add(exampleObject);
ProjectionList pl = Projections.projectionList();
pl.add( Projections.property("id") );
pl.add(Projections.sqlProjection("abs(`pageNo`-"+pageNo+") as diff", new String[] {"diff"}, types ));
crit.setProjection(pl);
但是当我添加
crit.addOrder(Order.asc("diff"));
我得到一个 org.hibernate.QueryException:无法解析属性:差异 例外。解决方法与 这 也不行。
附:因为我找不到任何关于 Hibernate 使用 QBE 的详细文档,所以上面的所有内容主要是试错方法
ProjectionList pl = Projections.projectionList();
pl.add(Projections.property("id"));
pl.add(Projections.sqlProjection("abs(`pageNo`-" + pageNo + ") as diff", new String[] {"diff"}, types ), diff); ---- solution
crit.addOrder(Order.asc("diff"));
crit.setProjection(pl);
我并不是这样认为,我能找到的是“这个”一词。导致冬眠不在其查询中包括任何限制,这意味着它获得了所有记录列表。关于报告的休眠错误,我可以看到它被报告为已修复,但我完全无法下载补丁。