关于java:将SQL语句转换为hibernate条件(具有count子句)

SQL statement conversion to hibernate criteria (having count clause)

我有一个SQL查询,希望将其转换为条件(hibernate3.3.2)以将其用于我的持久性层。
那就是查询:

1
2
3
4
5
6
select last_name
  from member
  where
    member.end_date > SYSDATE
  group by member.last_name
  having count(member.last_name) >1;

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

1
2
3
4
5
6
7
8
9
10
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_":无效的标识符

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

  • hibernate条件:按子句分组的投影计数

  • 具有某些条件的hibernate计数行

  • 我们如何使用Hibernate计算行数?

  • 如何在hibernate状态下使用HAVING COUNT(*)

  • hibernate标准API-HAVING子句可解决

我认为我离解决方案不远,但是有人可以帮助我吗?
如果您有任何疑问,请随时问我。
而且,如果您找到了另一个解决方法让我粘贴到此查询中,请不要犹豫地提出它...


您好,如果我是对的,您目前无法在hibernate条件中直接使用Haveing子句计数,请在经过修改的查询下方找到。如果不起作用,请发布整个堆栈跟踪

1
2
3
4
5
6
7
8
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
2
3
4
5
6
7
8
9
10
11
12
13
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;

它显示数据库中所有具有同名(相同名称)的成员。因此,供您参考,这是我的最终标准:

1
2
3
4
5
6
7
8
9
10
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));

为了稍微解释一下,通过投影,我计算了行数,然后将(select的)姓氏与主查询的姓氏进行了比较。
同样,始终需要主要标准的第二行。如果使用子查询(DetachedCriteria),则必须使用Projection。
但是,最后,我使用了HQL查询来运行我的代码,因为该标准使工作更加繁重...

所以,谢谢您的回答...


我根据您的主张修改了代码,这就是我的意思:

1
2
3
4
5
6
7
8
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查询格式,这就是说它能够执行:

1
2
3
4
5
6
7
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);

那么,可以使用该查询为我提供想要的结果吗?