【问题标题】:Hibernate HQL Count Distinct not working?Hibernate HQL Count Distinct 不起作用?
【发布时间】:2013-09-18 10:51:06
【问题描述】:

我有以下课程:

class User {
  hasMany = [ratings: Rating] 
} 

class Item {
 hasMany = [ratings: Rating]
}

class Rating {
 belongsTo = [user: User, item: Item]
}

我想统计对某个项目进行评分的不同用户。

以下不起作用:

select count(distinct(r.user)) from Rating as r
        where r.item=:item
        group by r.user

我必须如何修改 HQL 查询才能使其正常工作?

【问题讨论】:

    标签: java spring hibernate grails hql


    【解决方案1】:

    这是在 Hibernate Criteria 中的做法

    Criteria crit = session.createCriteria(Rating.class)
    .add(Restrictions.like("item", item)
    .addOrder(Order.asc("user"))
    .setProjection(
           Projections.distinct(Projections.projectionList()
                            .add(Projections.property("user"), "user")))
    .setResultTransformer(Transformers.aliasToBean(Rating.class));
    

    【讨论】:

    • 如何使用 HQL 做到这一点?
    • 从 Rating r 中选择不同的 r.user 其中 r.item=:item group by r.user;然后做一个 size()?
    • 有没有办法在一个查询中做到这一点?
    • 这样做是没有用的,因为您将列出 每个 记录只是为了查看其中有多少。有关使用标准的更好示例,请参阅stackoverflow.com/questions/22164717/…
    • 请注意,标准 API 有一个 Projections.countDistinct()。如果您使用它,它将以更少的代码提供正确的行为。我认为你可以使用 crit.setProjection(Projections.countDistinct("user"));
    【解决方案2】:

    您的查询应该按预期工作,只需对您使用 distinct 的方式稍作修改:

    select count(distinct r.user) from Rating as r 
    where r.item = :item group by r.user
    

    执行此查询的另一种但更冗长的方法是使用User 和join:

    select count(distinct u) from User as u 
    inner join u.ratings as r where r.item = :item
    group by r.user
    

    【讨论】:

    • 非常奇怪的是,在 distinct 计数中的额外括号会导致它因语法错误而失败。这是正确的解决方法。当然为我节省了大量时间。
    【解决方案3】:

    只需在事务中运行查询。

    Transaction tx=session.beginTransaction;
    //Run your query here
    tx.commit();
    

    问题是由于休眠缓存而出现的。

    【讨论】:

      猜你喜欢
      • 2012-10-21
      • 2020-04-05
      • 1970-01-01
      • 1970-01-01
      • 2015-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多