JPA Criteria查询组仅使用id

Ras*_*eri 10 java hibernate jpa group-by criteriaquery

这是一个示例实体:

public class Account{

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

public class AccountType{
   @Id
   Long id;
   String name;
}  
Run Code Online (Sandbox Code Playgroud)

现在我使用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();  
Run Code Online (Sandbox Code Playgroud)

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

select accType.id, accType.name, sum(acc.remaining)
from account acc join accType on acc.accounttype_id = accType.id
group by accType.id  
Run Code Online (Sandbox Code Playgroud)

上面的代码在PosgreSQL中工作,但无法在Oracle中运行,因为在其中选择未出现在group by子句中的accType.name.

更新:
我认为我的问题不清楚.我的问题不是关于PostgreSQL或Oracle的行为group by.我的问题是:
我使用typeJoinin group by子句(这意味着我希望hibernate使用AccountType的所有字段group by),但为什么hibernate只使用identity字段group by?如果我将只使用身份字段,group by那么我可以使用以下语句:

criteriaQuery.groupBy(typeJoin.get(AccountType_.id)) ;
Run Code Online (Sandbox Code Playgroud)

Vla*_*cea 9

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();  
Run Code Online (Sandbox Code Playgroud)


out*_*dev 6

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

来自Oracle 文档

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

来自PostgreSQL 文档

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