You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate使用Criteria查询如何排除继承子类仅返回父类数据

问题场景

定义了带内部子类的实体映射结构如下:

@Entity
@Table(name = "TABLE_A")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class ClassA {
    // 父类通用字段

    @Entity
    @Table(name = "TABLE_B")
    public static class ClassB extends ClassA {
        // 子类独有字段
    }
}

调用session.createCriteria(ClassA.class)期望仅查询TABLE_A表数据时,实际返回结果同时包含了TABLE_A和TABLE_B两张表的记录,需要实现仅返回父类对应表数据的效果。

实现方法

TABLE_PER_CLASS策略下默认查询父类会自动UNION所有子类表数据,要实现仅查询父类表数据可以选以下两种方案:

  • 方案1:Hibernate环境下用@Polymorphism注解(性能最优)
    在父类ClassA上添加Hibernate原生注解:

    @Polymorphism(type = PolymorphismType.EXPLICIT)
    

    配置完成后,所有针对ClassA的查询会直接生成只查TABLE_A单表的SQL,不会关联、聚合任何子类表的数据,直接从根源避免查出子类记录。
    注意这个是Hibernate专属注解,不属于JPA标准规范,如果需要兼容不同JPA实现可以选方案2。

  • 方案2:查询时显式添加类型过滤(JPA标准兼容)
    不修改实体类配置,在构造查询语句时手动添加类型限制,只匹配ClassA本身的记录:
    传统Hibernate Criteria写法:

    List<ClassA> result = session.createCriteria(ClassA.class)
            .add(Restrictions.eq("class", ClassA.class))
            .list();
    

    JPQL/标准JPA Criteria写法,用TYPE关键字过滤:

    SELECT a FROM ClassA a WHERE TYPE(a) = ClassA
    

    这个方案是JPA标准语法,所有JPA实现都支持,缺点是最终生成的SQL依然会和子类表做UNION操作,只是通过类型字段过滤掉子类记录,性能比方案1差。

内容的提问来源于stack exchange,提问作者eduardog3000

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 00:31:03