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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top