SQL语句转换为hibernate标准(有count子句)

时间:2012-09-04 06:58:40

标签: java sql hibernate criteria having

我有一个SQL查询,我想将其转换为标准(Hibernate 3.3.2),以将其用于我的持久层。 这是查询:

select last_name
  from member
  where
    member.end_date > SYSDATE
  group by member.last_name
  having count(member.last_name) >1;

我已经尝试了很多组合,但没有结果对我有好处......这是我的代码:

Criteria criteria = getSession(false).createCriteria(Member.ENTITY_NAME);
criteria.setProjection(Projections.projectionList()
            .add(Projections.groupProperty("lastName"))
            .add(Projections.count("lastName").as("cptLastName"))
            );
criteria.add(Restrictions.ge("endDate", now))
            .add(Restrictions.le("startDate", now))
            //.add(Restrictions.gt("cptLastName", new Integer(1)))
            .addOrder(Order.asc("lastName"))
;

使用注释行编写它时,我有一个对象列表,其中包含名称和名称在数据库中出现的次数。但是当我想要解除它时,这个错误: java.sql.SQLException:ORA-00904:“Y1_”:标识符无效

为了开发此代码,我受到以下不同帖子的启发:

我认为我的解决方案并不遥远,但是有人帮我吗? 如果您有疑问,请不要犹豫,问我。 如果您找到另一种解决方法让我粘贴到此查询,请不要犹豫,建议它......

3 个答案:

答案 0 :(得分:1)

如果我是对的,你现在不能直接在hibernate标准中使用having子句数,请在下面找到修改后的查询。如果它不起作用,请发布整个堆栈跟踪

DetachedCriteria innerQuery = DetachedCriteria.forClass(Member.ENTITY_NAME, "inner");
  innerQuery.setProjection(Projections.rowCount());
  innerQuery.add(Restrictions.eqProperty("lastName", "outer.lastName"));

  Criteria c = s.createCriteria(Member.ENTITY_NAME, "outer");
  c.setProjection(Projections.property("lastName"));
  c.add(Restrictions.gt("endDate", now))   
  c.add(Subqueries.eq(new Integer(1), innerQuery));

答案 1 :(得分:0)

我根据你的命题调整了我的代码,这就是我所拥有的:

DetachedCriteria innerQuery = DetachedCriteria.forEntityName(Member.ENTITY_NAME,"inner")
    .setProjection(Projections.rowCount())
    .add(Restrictions.eqProperty("lastName", "outer.lastName"));

Criteria criteria = getSession(false).createCriteria(Member.ENTITY_NAME, "outer")
    .setProjection(Projections.property("lastName"))
    .add(Restrictions.g("endDate", now))
    .add(Subqueries.gt(new Integer(1), innerQuery));

所以,就像我在上面的评论中说的那样,它可以工作,但需要很长时间......给我错误的结果(它应该给我八条记录)。

我激活了显示hibernate查询的选项(hibernate.show_sql = true)。如果我以sql查询格式格式化它,那就是它能够执行:

select this.last_name
from member this 
where this.END_DATE>=SYSDATE 
and 1 > 
    (select count(*) 
    from member inner  
    where inner.last_name = this.last_name);

那么,有什么可以用这个查询来给我结果我想要的呢?

答案 2 :(得分:0)

事实上,我的答案部分取得了成功......因为我只展示了我的一个重要请求。就像这样:

select member.last_name, member.first_name, 
from member
where  
  member.end_date > SYSDATE
and
  member.last_name in 
  (select member.last_name
  from member 
  where
    member.end_date > SYSDATE
  group by member.last_name
  having count(member.last_name) >1)
order by member.last_name;

它显示数据库中具有同音词(同名)的所有成员。因此,对于您的信息,这是我的最终标准:

Calendar now = Calendar.getInstance();
DetachedCriteria innerQuery = DetachedCriteria.forEntityName(Member.ENTITY_NAME,"inner")
        .setProjection(Projections.rowCount())
        .add(Restrictions.eqProperty("lastName", "outer.lastName"))
        .add(Restrictions.ge("endDate", now));

Criteria criteria = getSession(false).createCriteria(Member.ENTITY_NAME, "outer")
        .setProjection(Projections.property("lastName"))                
        .add(Restrictions.ge("endDate", now))
        .add(Subqueries.lt(new Integer(1), innerQuery));

为了解释一下,使用投影,我计算行数,并将姓氏(选择的)与主查询的姓氏进行比较。 此外,始终需要主要标准的第二行。如果使用子查询(DetachedCriteria),则必须使用Projection。 但是,最后,我使用HQL查询来运行我的代码,因为标准更加繁重......

所以,谢谢你回答......