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

Hibernate父类无表、子类分表的关联映射与ID处理问题咨询

解决方案

要解决这个问题,你需要使用Hibernate的TABLE_PER_CLASS继承映射策略,既让父类CommonBon成为可被关联的实体,又允许子类拥有各自独立的ID字段和数据库表。具体步骤如下:

1. 调整CommonBon的注解

将CommonBon标记为@Entity,并指定继承策略为TABLE_PER_CLASS,这样Hibernate不会为父类生成单独的表,而是让每个子类对应自己的数据库表:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class CommonBon {
    // 这里不要定义@Id,由子类各自实现主键
    // 其他公共字段和方法
    private Integer displayNo;
    
    // 与CommonProduct的双向关联
    @ManyToOne
    @JoinColumn(name = "PRODUCT_ID")
    private CommonProduct product;
    
    // getter/setter方法
}

2. 在子类中定义各自的ID

在Bon和BonHistory中分别添加自己的@Id字段,对应数据库表的主键:

Bon类:

@Entity
@Table(name = "Bon")
public class Bon extends CommonBon {
    @Id
    @Column(name = "BON_ID")
    private Long bonId;
    
    // 子类特有的字段和方法
    // getter/setter方法
}

BonHistory类:

@Entity
@Table(name = "BonHistory")
public class BonHistory extends CommonBon {
    @Id
    @Column(name = "BON_HISTORY_ID")
    private Long bonHistoryId;
    
    // 子类特有的字段和方法
    // getter/setter方法
}

3. 保留CommonProduct的关联

现在CommonBon是实体类,CommonProduct中的@OneToMany关联可以正常工作:

@MappedSuperclass
public abstract class CommonProduct {
    @OneToMany(mappedBy = "product", cascade = CascadeType.ALL, orphanRemoval = true)
    @OrderBy("displayNo")
    private Set<CommonBon> bons = new LinkedHashSet<>();
    
    // getter/setter方法
}

原理说明

  • TABLE_PER_CLASS策略允许每个子类拥有独立的数据库表,每张表包含父类的所有字段+子类特有字段,同时各自维护自己的主键。
  • 父类CommonBon作为抽象实体,既满足了@OneToMany关联对实体类的要求,又不会生成冗余的数据库表。
  • 双向关联中mappedBy = "product"指向CommonBon中的product字段,Hibernate会自动处理两个子类与CommonProduct的关联关系。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 13:32:18