SpringBoot中JPA Hibernate一对一复合主键映射问题求助
SpringBoot JPA映射Oracle复合主键一对一关系的解决方案
问题根源
- @MapsId使用错误:默认情况下
@MapsId会尝试将关联实体的主键映射到当前实体名为id的属性,但你的MasterDetails的嵌入式主键MasterDetailsId字段名(masterId/version)与Master的主键MasterId字段名(id/version)不匹配,导致Hibernate找不到映射字段,启动报错。 - 移除@MapsId后的主键生成问题:此时Hibernate无法感知
MasterDetails的主键应从关联的Master主键继承,插入时未自动赋值主键,同时因关联映射不完整,未生成外键约束。
修正方案
核心调整:复用主表主键类,修正列名映射
直接复用MasterId作为MasterDetails的嵌入式主键,通过@AttributeOverrides调整数据库列名映射,配合@MapsId实现主键关联。
完整修正代码
Master.java
@Getter @Setter @Entity @Table(name = "master") public class Master { @EmbeddedId private MasterId id; // 添加级联操作,确保Master操作同步到MasterDetails @OneToOne(mappedBy = "master", cascade = CascadeType.ALL, orphanRemoval = true) private MasterDetails masterDetails; }
MasterId.java(无需修改)
@Getter @Setter @Embeddable public class MasterId implements Serializable { private static final long serialVersionUID = 8254837075462858051L; @Column(name = "id", nullable = false) private BigDecimal id; @Lob @Column(name = "version", nullable = false) private String version; }
MasterDetails.java
@Getter @Setter @Entity @Table(name = "master_details") public class MasterDetails { // 复用MasterId作为主键,通过AttributeOverrides调整列名映射 @EmbeddedId @AttributeOverrides({ @AttributeOverride(name = "id", column = @Column(name = "master_id", nullable = false)), @AttributeOverride(name = "version", column = @Column(name = "version", nullable = false)) }) private MasterId id; // @MapsId自动将Master的主键赋值给当前实体的EmbeddedId @MapsId @OneToOne(fetch = FetchType.LAZY, optional = false) @JoinColumns({ @JoinColumn(name = "master_id", referencedColumnName = "id", nullable = false), @JoinColumn(name = "version", referencedColumnName = "version", nullable = false) }) private Master master; @Lob @Column(name = "details", nullable = false) private String details; }
说明
- 删除原
MasterDetailsId.java,无需单独定义细节表主键类,复用主表主键类减少冗余。 @AttributeOverrides将MasterId中的id字段映射到master_details表的master_id列,与数据库结构匹配。@MapsId让Hibernate自动从关联的Master实例中获取主键值,赋值给MasterDetails的主键,解决插入时主键为null的问题。cascade = CascadeType.ALL确保保存/更新/删除Master时,同步操作关联的MasterDetails;orphanRemoval = true保证当Master与MasterDetails解除关联时,自动删除MasterDetails记录。
数据库层面无需调整
原表的复合主键、外键约束设计符合一对一关联要求,无需修改数据库结构。
内容的提问来源于stack exchange,提问作者developer
相关产品推荐
相关产品推荐

