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
相关产品推荐
相关产品推荐

