14

这是一个示例实体:

public class Account{

   @Id
   Long id
   Double remaining;
   @ManyToOne
   AccountType type
}

public class AccountType{
   @Id
   Long id;
   String name;
}  

现在我使用 Join 创建一个条件查询,如下所示:

CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
CriteriaQuery criteriaQuery = criteriaBuilder.createquery();
Root<Account> accountRoot = criteriaQuery.from(Account.class);
Join<Account, AccountType> typeJoin = accountRoot.join(Account_.type);

criteriaQuery.multiSelect(
    typeJoin,
    criteriaBuilder.sum(accountRoot.get(Account_.remaining))
);

criteriaQuery.groupBy(typeJoin);
Query query = getEntityManager().createQuery(criteriaQuery);
query.getResultList();  

上面的代码生成如下 Sql 命令:

select accType.id, accType.name, sum(acc.remaining)
from account acc join accType on acc.accounttype_id = accType.id
group by accType.id  

上面的代码在 PosgreSQL 中工作,但不能在 Oracle 中运行,因为在其中选择了没有出现在 group by 子句中的 accType.name。

更新
我认为我的问题对你来说并不清楚。我的问题不是关于group by. 我的问题是:
我使用typeJoiningroup by子句(这意味着我希望休眠使用 AccountType in 的所有字段group by),但为什么休眠只使用身份字段group by?如果我只使用身份字段,group by那么我可以使用以下语句:

criteriaQuery.groupBy(typeJoin.get(AccountType_.id)) ;
4

2 回答 2

13

JPA/Hibernate 不会自动在 group by 子句中包含所有实体属性,因此您必须手动指定它们:

CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
CriteriaQuery criteriaQuery = criteriaBuilder.createQuery();
Root<Account> accountRoot = criteriaQuery.from(Account.class);
Join<Account, AccountType> typeJoin = accountRoot.join(Account_.type);

criteriaQuery.multiSelect(
    typeJoin.get("id"),
    typeJoin.get("name"),
    criteriaBuilder.sum(accountRoot.get(Account_.remaining))
);

criteriaQuery.groupBy(typeJoin.get("id"), typeJoin.get("name"));
Query query = getEntityManager().createQuery(criteriaQuery);
query.getResultList();  
于 2015-01-02T15:31:20.180 回答
4

如果使用 GROUP BY,Oracle 要求选择列表中的每一列都在 GROUP BY 中。
PostgreSQL 是一样的,除了按主键分组时,它允许您选择任何列。

来自Oracle 文档

在包含 GROUP BY 子句的查询中,选择列表的元素可以是聚合函数、GROUP BY 表达式、常量或涉及其中之一的表达式。

来自PostgreSQL 文档

当存在 GROUP BY 或存在任何聚合函数时,SELECT 列表表达式引用未分组列是无效的,除非在聚合函数内或当未分组列在功能上依赖于分组列时,否则会有更多为未分组的列返回一个可能的值。如果分组列(或其子集)是包含未分组列的表的主键,则存在功能依赖性。

于 2015-01-05T21:33:14.413 回答