Java Hibernate按示例和投影查询

Java Hibernate按示例和投影查询,java,hibernate,criteria,projection,Java,Hibernate,Criteria,Projection,简而言之:hibernate不支持投影和示例查询?我发现这个帖子: 代码如下: User usr = new User(); usr.setCity = 'TEST'; getCurrentSession().createCriteria(User.class) .setProjection( Projections.distinct( Projections.projectionList() .add( Projections.property("name"), "name") .add( P

简而言之: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\?而不是这个城市

我已经尝试了几种方法,并搜索了问题跟踪程序,但没有找到任何相关信息

我甚至尝试使用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));

有人使用过projections and query by example吗?

我能看看你的用户类吗?这只是使用下面的限制。我不明白为什么限制与示例有什么不同(我认为在示例中默认情况下会忽略空字段)

我从未使用过alaistToBean,但我只是读过它。你也可以把结果循环一下

List<Object> rows = criteria.list();
for(Object r: rows){
  Object[] row = (Object[]) r;
  Type t = ((<Type>) row[0]);
}
List rows=criteria.List();
用于(对象r:行){
对象[]行=(对象[])r;
类型t=(()行[0]);
}
如果有必要,您可以通过这种方式手动填充用户


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

当您的别名与objects属性同名时,问题似乎会发生。Hibernate似乎选择了别名并在sql中使用它。我发现这是有文档记录的,我相信这是Hibernate中的一个bug,尽管我不确定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));
这导致了一个错误: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));

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

我面临一个类似的问题。我正在使用queryby-Example,我想按自定义字段对结果进行排序。在SQL中,我将执行以下操作:

select pageNo, abs(pageNo - 434) as diff
from relA
where year = 2009
order by diff
如果没有ORDERBY条款,它可以正常工作。我得到的是

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:无法解析属性:diff异常。解决这个问题的方法也不起作用


PS:由于我找不到任何关于QBE在Hibernate中使用的详细文档,上面的内容主要是尝试和错误方法

这里真正的问题是Hibernate中有一个bug,它在where子句中使用了select list别名:


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

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

您能显示完整生成的sql吗?我添加了一个解决方案,其中包括在我遇到类似问题时生成的sql。保罗:我很高兴它有所帮助。我感到惊讶的是,这个答案一直没有被注意到,因为它似乎是一个大问题,而且这个解决方案不是直观的或有文档记录的。相关的Hibernate错误在Hibernate的3.6.0Beta4版本中被标记为已修复。@RyanCook Hi!这个解决方案是可行的,但我想知道是否有一个示例解决方案,因为我们可以有多达10个过滤器(即10个限制),并且我们必须为每个过滤器验证字段是否为null或空。在这个问题上,我花了2天的时间
这个
关键字很好地解决了这个问题。非常感谢@RyanI对Order.asc(“sectionHeader”)还有其他问题。当我在投影中使用相同的属性时,也会使用限制和顺序!!在sqlProjection之后添加aliias,这将用于排序
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);
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"));
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);