HQL - 按连接继承类型映射的实体分组不起作用

Posted

技术标签:

【中文标题】HQL - 按连接继承类型映射的实体分组不起作用【英文标题】:HQL - Group by entities mapped with joined inheritance type not working 【发布时间】:2021-12-17 10:09:09 【问题描述】:

Group by entities is possible in HQL,但似乎通过连接继承映射的实体没有。

select a, count(r) from Root r join r.a a group by a

执行上述查询会导致group by中列数不足的sql:

select
    suba1_.id as col_0_0_,
    count(root0_.id) as col_1_0_,
    suba1_.id as id1_12_,
    suba1_1_.super_data as super_da2_12_,
    suba1_.sub_data as sub_data1_10_ 
from root root0_ 
inner join suba suba1_ on root0_.a_id=suba1_.id 
inner join supera suba1_1_ on suba1_.id=suba1_1_.id 
group by suba1_.id

它给出了以下错误消息:

o.h.engine.jdbc.spi.SqlExceptionHelper: expression not in aggregate or GROUP BY columns: SUPERA1_.SUPER_DATA in statement

实体描述如下:

@Entity
public class Root 
    private @Id Integer id;
    @ManyToOne
    private SubA a;


@Entity
public class SubA extends SuperA 
    private String subData;


@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class SuperA 
    private @Id Long id;
    private String superData;

另外如果把Root::a的类型改成SuperA,hql生成的sql也会出现同样的问题。

那么可以按具有联合继承类型的实体分组还是我遗漏了什么?

PS。如果 SuperA 映射到每个类继承类型的表,则此 hql 查询确实有效,但如果 R​​oot::a 的类型也更改为 SuperA,则会失败并出现同样的问题。

休眠版本:org.hibernate:hibernate-core:jar:5.4.32.Final:compile

【问题讨论】:

如果你这样做:select a, count(r) from Root r join r.a a group by a 实际上这是我的原始查询,“按 a.id 分组”可能是其他一些从中复制的测试。所以同样的问题。 【参考方案1】:

是的,有点诡计,回答我自己的问题。 sql 中 group by 的缺失列是 SuperA 的列 id,因此解决方案是包含它。我发现可以通过将超类的 id 映射到一个额外的列,并在实体旁边的组中引用它。

因此,在SuperA 中将添加一个额外的列映射superId

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class SuperA 
    private @Id Long id;
    @Column(name="id", updatable = false, insertable = false)
    private Long superId;
    private String superData;

并在组中引用

select a, count(r) from Root r join r.a a group by a, a.superId

此解决方案仅针对 HSQLDB 和 PostgreSQL 进行了测试。

【讨论】:

以上是关于HQL - 按连接继承类型映射的实体分组不起作用的主要内容,如果未能解决你的问题,请参考以下文章

分组按选择不起作用

Java JPA双向ManyToOne映射不起作用

猪按命令分组不起作用

Informatica Cloud DB2 for i cdc 连接类型 SQL 覆盖不起作用

c ++多级继承不起作用[重复]

JPA实体继承实体的映射策略