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

采用TABLE_PER_CLASS继承查询两张数据库表时抛出异常

问题分析与解决方案

问题根源

你遇到的Table 'r_db.TableBase' doesn't exist异常,核心原因是使用InheritanceType.TABLE_PER_CLASS继承策略时,Hibernate对非抽象父实体类的处理逻辑:

  • 当父类TableBase被标记为@Entity且非抽象时,Hibernate会将其视为具体实体,默认认为数据库中存在对应的TableBase表;
  • 执行select e from TableBase e查询时,Hibernate会尝试访问这张不存在的表,从而抛出异常。

最优解决方案:将父类改为抽象类

只需把TableBase改为抽象类,保留原有的@Entity和TABLE_PER_CLASS注解即可。此时Hibernate会识别这是一个抽象父类,不会去寻找对应的物理表,而是自动通过UNION ALL合并所有子类对应的表(TABLE_1、TABLE_2)的数据。

修改后的父类代码:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class TableBase {

        @Id
        @Column(name="NAME")
        private String name;

        @Column(name="PHONE")
        private String phoneNumber;


        public String getPhoneNumber() {
                return phoneNumber;
        }

        public void setPhoneNumber(String phone) {
                this.phoneNumber = phone;
        }
}

原查询代码无需任何修改,执行后即可正常返回两张表的合并数据。

备选解决方案

如果无法将父类改为抽象类,可以选择以下两种方式:

方式1:改用@MappedSuperclass

将父类的@Entity注解替换为@MappedSuperclass,此时父类不再是JPA实体,仅作为子类的字段映射模板。需要手动合并两个子类的查询结果:

父类修改:

@MappedSuperclass
public class TableBase {
        // 字段和方法保持不变
}

查询代码调整:

public ArrayList<TableBase> getUsers(){
    AppEntityManager appEntMgr = AppEntityManager.getAppEntityManager();
    appEntMgr.startTransaction();
    
    List<Table1> table1Data = appEntMgr.createQuery("select e from Table1 e", Table1.class)
                .setFirstResult(0)
                .setMaxResults(10)
                .getResultList();
    List<Table2> table2Data = appEntMgr.createQuery("select e from Table2 e", Table2.class)
                .setFirstResult(0)
                .setMaxResults(10)
                .getResultList();
    
    ArrayList<TableBase> result = new ArrayList<>();
    result.addAll(table1Data);
    result.addAll(table2Data);
    // 若需要全局分页,需自行处理数据截取逻辑
    return result;
}

方式2:使用显式UNION查询

保留父类原注解,通过JPQL的UNION语法直接查询两个子类并合并结果:

查询代码修改:

public ArrayList<TableBase> getUsers(){
    AppEntityManager appEntMgr = AppEntityManager.getAppEntityManager();
    appEntMgr.startTransaction();
    
    String jpql = "SELECT e FROM Table1 e UNION SELECT e FROM Table2 e";
    return (ArrayList<TableBase>) appEntMgr.createQuery(jpql, TableBase.class)
                .setFirstResult(0)
                .setMaxResults(10)
                .getResultList();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 13:01:44