23

简而言之: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

我已经尝试了几种方法,并搜索了问题跟踪器,但一无所获。

我什至尝试使用投影别名和变形金刚,但它不起作用:

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));

有没有人通过示例使用预测和查询?

4

6 回答 6

45

当您有一个与 objects 属性同名的别名时,问题似乎就会发生。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_": invalid identifier

但是,当我将限制更改为使用“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 ? ) 

就是这样!一个非常简单的解决一个痛苦的问题。我不知道此修复程序如何通过示例问题转化为查询,但它可能会让您更接近。

于 2009-06-06T18:41:58.247 回答
16

我可以看看你的用户类吗?这只是使用下面的限制。我不明白为什么 Restrictions 与 Example 有任何不同(我认为 null 字段在示例中默认被忽略)。

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]);
}

如果必须,您可以通过这种方式自己手动填充用户。

如果没有更多信息来诊断问题,就很难调查这个问题。

于 2008-09-17T19:34:29.767 回答
6

这里真正的问题是hibernate中有一个错误,它在where子句中使用了选择列表别名:

http://opensource.atlassian.com/projects/hibernate/browse/HHH-817

万一有人来这里寻找答案,去看看票。修复花了 5 年时间,但理论上它会在下一个版本中出现,然后我怀疑你的问题会消失。

于 2010-09-15T17:42:46.880 回答
0

我面临着类似的问题。我正在使用按示例查询,我想按自定义字段对结果进行排序。在 SQL 中,我会执行以下操作:

select pageNo, abs(pageNo - 434) as diff
from relA
where year = 2009
order by diff

没有 order-by-clause 可以正常工作。我得到的是

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: could not resolve property: diff异常。解决问题的方法也不起作用。

PS:由于我找不到任何关于使用 QBE for Hibernate 的详细文档,以上所有内容主要是试错法

于 2009-06-10T16:07:38.527 回答
0
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);
于 2016-02-13T15:11:08.050 回答
-1

我真的不这么认为,我能找到的是“这个”这个词。导致休眠在其查询中不包含任何限制,这意味着它获得了所有记录列表。关于报告的休眠错误,我可以看到它已报告为已修复,但我完全无法下载补丁。

于 2011-07-11T08:11:08.127 回答