Spring Boot 3.1.4中EmbeddedId的mappedBy配置失效问题
Spring Boot 3.1.4中EmbeddedId关联的mappedBy配置异常解决方案
升级至Spring Boot 3.1.4后,原本在旧版本中正常工作的mappedBy = "id.globalId"配置出现异常,这是因为Spring Boot 3.1.x对应的Hibernate 6.2.x对关联映射的路径解析做了严格规范,不再支持直接通过EmbeddedId的属性路径作为mappedBy的值。
原问题代码示例
关联EmbeddedId的实体:
@Entity @Getter @Setter(AccessLevel.PROTECTED) @Table(name = "STATUS") public class Status { @Id private String id; @OneToMany(mappedBy = "id.globalId") private List<StatusLabel> labels; }
包含EmbeddedId的实体:
@Entity @Getter @Setter(AccessLevel.PROTECTED) @Table(name = "STATUS_LABELS") public class StatusLabel { @EmbeddedId private LabelGlobalId id; private String labelname; private String shortname; }
EmbeddedId定义:
@Embeddable @Getter @Setter(AccessLevel.PROTECTED) public class LabelGlobalId implements Serializable { private String globalId; private String langId; }
解决方案
方案1:添加显式@ManyToOne关联属性
在StatusLabel中新增与Status的关联属性,并用insertable = false, updatable = false避免字段重复操作:
@Entity @Getter @Setter(AccessLevel.PROTECTED) @Table(name = "STATUS_LABELS") public class StatusLabel { @EmbeddedId private LabelGlobalId id; @ManyToOne @JoinColumn(name = "globalId", insertable = false, updatable = false) private Status status; private String labelname; private String shortname; }
修改Status中的@OneToMany配置,指向新增的关联属性:
@OneToMany(mappedBy = "status") private List<StatusLabel> labels;
方案2:使用@MapsId映射EmbeddedId属性
通过@MapsId直接将Status的主键映射到LabelGlobalId的globalId属性,更贴合嵌入式ID的关联规范:
@Entity @Getter @Setter(AccessLevel.PROTECTED) @Table(name = "STATUS_LABELS") public class StatusLabel { @EmbeddedId private LabelGlobalId id; @ManyToOne @MapsId("globalId") // 关联EmbeddedId中的globalId属性 @JoinColumn(name = "globalId") private Status status; private String labelname; private String shortname; }
同样修改Status中的@OneToMany配置:
@OneToMany(mappedBy = "status") private List<StatusLabel> labels;
原因说明
Spring Boot 3.1.4依赖的Hibernate 6.2.x强化了映射规则的规范性,不再允许直接通过EmbeddedId的属性路径(如id.globalId)作为mappedBy的值,必须通过实体间显式的关联属性来维护映射关系。
内容的提问来源于stack exchange,提问作者stylepatrick
相关产品推荐
相关产品推荐

