1

我有一个 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_": invalid identifier

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

我想我离解决方案不远,但有没有人可以帮助我?如果您有任何问题,请随时问我。如果您找到了另一种解决方法让我粘贴到此查询中,请不要犹豫提出它...

4

3 回答 3

1

嗨,如果我是对的,您现在不能直接在休眠条件中使用 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));
于 2012-09-04T12:29:23.333 回答
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.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);

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

于 2012-09-05T09:20:04.963 回答
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 查询来运行我的代码,因为条件更繁重......

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

于 2012-09-12T13:02:51.080 回答