




hibernate 默认采用 single_table 策略,导致子类 worddoc 被错误插入 basedoc 表;需显式配置 @inheritance 或改用 @mappedsuperclass 才能按预期分表存储。
在 JPA/Hibernate 中,继承关系的持久化行为并非由类结构自动推断,而是严格依赖显式的继承映射策略(Inheritance Strategy)。你当前的实体定义未声明任何策略,因此 Hibernate 默认启用 SINGLE_TABLE 模式——即所有继承体系中的实体共享一个表(以最顶层非抽象类或显式指定的根表为准)。这正是错误的根本原因:
适用于你已存在 WORD_DOC 和 BASEDOC 物理表、且希望保持表间一对一继承关系的场景:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "BASEDOC")
public abstract class BaseDoc {
@Id
private Long id;
// 公共字段...
}
@Entity
@Table(name = "DOC")
public class Doc extends BaseDoc {
// Doc 特有字段...
}
@Entity
@Table(name = "WORD_DOC")
public class WordDoc extends Doc {
private String contentType;
// 其他 WordDoc 特有字段...
}? 说明:JOINED 会为每个 @Entity 类生成独立表,通过主键外键关联(如 WORD_DOC.id → DOC.id → BASEDOC.id)。查询时自动 JOIN,插入时分表写入——完全匹配你现有的数据库设计。
若 BaseDoc 仅提供公共字段和逻辑,本身不对应任何数据库表(即纯粹是代码复用层),应移除 @Entity,改为:
@MappedSuperclass
public abstract class BaseDoc {
@Id
protected Long id;
@Version
protected Long version; // 现在 version 属于子表
}此时 Doc 和 WordDoc 各自映射到 DOC 和 WORD_DOC 表,BaseDoc 的字段(含 id, version)会被自动继承到各子表中,无需额外配置。
⚠️ 注意:@MappedSuperclass 类不能被查询、不能作为 @ManyToOne 目标,且无独立生命周期。
若坚持用 SINGLE_TABLE,则必须合并所有字段到一张表(如全存 BASEDOC),并添加 @DiscriminatorColumn 区分类型,但这与你现有双表结构冲突,会引发严重维护问题。

正确配置后,WordDoc 将只插入 WORD_DOC 表,version 等字段自然落库,彻底解决跨表插入异常。