You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 2迁3启动报错:@MapsId指定字段不存在的解决方案咨询

Spring Boot 2迁移至Spring Boot 3后@MapsId映射错误解决方案

问题原因

错误核心是Hibernate 6(Spring Boot 3默认依赖版本)对@MapsId的字段匹配规则更严格:你的嵌入ID类CorporateAccountLinkageKey中属性使用驼峰命名(如corporateAccountId),但@MapsId注解里写的是数据库列名的下划线格式(如corporate_account_id),Hibernate 6无法自动将下划线名称映射到驼峰属性,导致找不到对应字段。

解决方案

不需要替换@MapsId注解,只需让@MapsId指定的名称与嵌入ID类中的属性名一致即可,无需修改嵌入ID类本身。


修改后的实体类代码

import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.MapsId;
import jakarta.persistence.Table;

@Entity
@Table(name = "corporate_account_linkages")
public class CorporateAccountLinkage {

  @EmbeddedId
  private CorporateAccountLinkageKey corporateAccountLinkageKey;

  @ManyToOne
  @MapsId("corporateAccountId") // 改为嵌入ID类中的驼峰属性名
  @JoinColumn(name = "corporate_account_id") // 数据库列名保留下划线格式不变
  private CorporateAccount corporateAccount; // 建议修正变量名,避免与ID属性混淆

  @ManyToOne
  @MapsId("linkedCorporateAccountId") // 改为嵌入ID类中的驼峰属性名
  @JoinColumn(name = "linked_corporate_account_id") // 数据库列名保留下划线格式不变
  private CorporateAccount linkedCorporateAccount; // 建议修正变量名,避免与ID属性混淆

  // 补充getter、setter方法
}

嵌入ID类(仅补充规范要求内容)

import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import java.io.Serializable;
import java.util.Objects;

@Embeddable
public class CorporateAccountLinkageKey implements Serializable {
    
  @Column(name = "corporate_account_id", nullable = false)
  private Long corporateAccountId;

  @Column(name = "linked_corporate_account_id", nullable = false)
  private Long linkedCorporateAccountId;

  // JPA规范强制要求:无参构造方法
  public CorporateAccountLinkageKey() {}

  // 全参构造方法
  public CorporateAccountLinkageKey(Long corporateAccountId, Long linkedCorporateAccountId) {
    this.corporateAccountId = corporateAccountId;
    this.linkedCorporateAccountId = linkedCorporateAccountId;
  }

  // JPA规范强制要求:equals和hashCode方法
  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    CorporateAccountLinkageKey that = (CorporateAccountLinkageKey) o;
    return Objects.equals(corporateAccountId, that.corporateAccountId) 
        && Objects.equals(linkedCorporateAccountId, that.linkedCorporateAccountId);
  }

  @Override
  public int hashCode() {
    return Objects.hash(corporateAccountId, linkedCorporateAccountId);
  }

  // 补充getter、setter方法
  public Long getCorporateAccountId() {
    return corporateAccountId;
  }

  public void setCorporateAccountId(Long corporateAccountId) {
    this.corporateAccountId = corporateAccountId;
  }

  public Long getLinkedCorporateAccountId() {
    return linkedCorporateAccountId;
  }

  public void setLinkedCorporateAccountId(Long linkedCorporateAccountId) {
    this.linkedCorporateAccountId = linkedCorporateAccountId;
  }
}

额外说明

  1. @MapsId的参数必须是嵌入ID类中的属性名称,而非数据库列名,这是Hibernate 6严格遵循JPA规范的表现,Spring Boot 2依赖的Hibernate 5对该规则校验更宽松,允许混用列名与属性名。
  2. 嵌入ID类必须实现Serializable接口,同时提供无参构造、equals和hashCode方法,这是JPA的强制要求,Hibernate 6会严格校验这些规范。

内容的提问来源于stack exchange,提问作者Peter Penzov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 13:58:28