迁移Hibernate配置至注解遇双@Id及类型转换错误求助
问题分析与解决方案
你当前的核心问题是错误使用了继承映射(@Inheritance)来实现两个表的关联关系,而实际需求是InstrumentOfferingHistory与InstrumentOffering为多对一关联,并非父子继承关系。Joined继承策略要求子类主键必须与父类主键绑定(子类主键同时作为父类的外键),但你给子类添加了独立@Id,这直接违反了该策略的规则,导致Hibernate抛出类型转换错误。
以下是两种可行的解决方案:
方案1:直接拆分独立实体(推荐)
完全去掉继承关系,将两个表定义为独立的实体类,在InstrumentOfferingHistory中通过@ManyToOne建立关联,各自保留独立主键。
InstrumentOffering 实体
@Entity @Table(name = "INSTRUMENT_OFFERINGS") public class InstrumentOffering { @Id @Column(name = "INSTRUMENT_OFFERING_ID") private Long instrumentOfferingId; // 其他业务字段、getter/setter }
InstrumentOfferingHistory 实体
@Entity @Table(name = "INSTRUMENT_OFFERINGS_HISTORY") public class InstrumentOfferingHistory { @Id @Column(name = "INSTRUMENT_HISTORY_ID") private Long instrumentHistoryId; @ManyToOne @JoinColumn(name = "INSTR_OFFERINGS_ID") // 对应历史表的外键列 private InstrumentOffering instrumentOffering; // 其他业务字段、getter/setter }
方案2:共享通用字段的抽象基类
如果两个表存在大量共享字段(如创建时间、操作人等),可以创建一个无主键的抽象基类(用@MappedSuperclass标记),让两个实体继承该基类,同时保留各自的独立主键和关联关系。
抽象基类
@MappedSuperclass public abstract class BaseOffering { // 共享字段示例 @Column(name = "CREATED_DATE") private LocalDateTime createdDate; @Column(name = "OPERATOR") private String operator; // getter/setter }
InstrumentOffering 实体
@Entity @Table(name = "INSTRUMENT_OFFERINGS") public class InstrumentOffering extends BaseOffering { @Id @Column(name = "INSTRUMENT_OFFERING_ID") private Long instrumentOfferingId; // 专属业务字段、getter/setter }
InstrumentOfferingHistory 实体
@Entity @Table(name = "INSTRUMENT_OFFERINGS_HISTORY") public class InstrumentOfferingHistory extends BaseOffering { @Id @Column(name = "INSTRUMENT_HISTORY_ID") private Long instrumentHistoryId; @ManyToOne @JoinColumn(name = "INSTR_OFFERINGS_ID") private InstrumentOffering instrumentOffering; // 专属业务字段、getter/setter }
补充说明
你提到原XML配置可正常运行,大概率是因为XML中并未配置继承关系,而是通过<many-to-one>标签定义了两个表的关联。迁移注解时需还原这种关联逻辑,而非错误地套用继承映射。
内容的提问来源于stack exchange,提问作者Michu93
相关产品推荐
相关产品推荐

