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

使用Lombok Builder插入复合主键Entity时ID类型错误的解决咨询

解决Spring Boot复合主键实体使用Lombok Builder保存时的类型错误问题

问题描述

使用Spring Boot 3.1.7,通过反向工程生成包含3个主键的实体类Apibs及对应复合主键类ApibsPK。使用Lombok Builder语法创建Apibs对象并执行保存操作时,抛出如下错误:

org.springframework.dao.InvalidDataAccessApiUsageException: Supplied id had wrong type: entity 'com.sageapservice.entity.mssql.Apibs' has id type 'class com.sageapservice.entity.mssql.ApibsPK' but supplied id was of type 'class java.lang.Integer'

尝试直接为实体字段赋值(报错),或创建ApibsPK对象作为ID传入,但Builder不接受未定义字段,程序无法运行。

现有代码

实体类Apibs

@Entity
@AllArgsConstructor
@Builder
@NoArgsConstructor
@IdClass(ApibsPK.class)
public class Apibs {
    @Id
    @Column(name = "CNTBTCH", nullable = false, precision = 0)
    private int cntbtch;

    @Id
    @Column(name = "CNTITEM", nullable = false, precision = 0)
    private int cntitem;

    @Id
    @Column(name = "CNTPAYM", nullable = false, precision = 0)
    private int cntpaym;

    @Basic
    @Column(name = "AUDTDATE", nullable = false, precision = 0)
    private int audtdate;

    @Basic
    @Column(name = "AUDTTIME", nullable = false, precision = 0)
    private int audttime;

    @Basic
    @Column(name = "AUDTUSER", nullable = false, length = 8)
    private String audtuser;

    @Basic
    @Column(name = "AUDTORG", nullable = false, length = 6)
    private String audtorg;

    @Basic
    @Column(name = "DATEDUE", nullable = false, precision = 0)
    private int datedue;
// ...
}

复合主键类ApibsPK

@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ApibsPK implements Serializable {
    @Column(name = "CNTBTCH", nullable = false, precision = 0)
    @Id
    private int cntbtch;

    @Column(name = "CNTITEM", nullable = false, precision = 0)
    @Id
    private int cntitem;

    @Column(name = "CNTPAYM", nullable = false, precision = 0)
    @Id
    private int cntpaym;
// ...
}

解决方案

1. 修正复合主键类的注解冗余

ApibsPK作为@IdClass指定的主键类,不需要@Id和@Column注解(这些注解仅需在实体类的主键字段上标注)。同时必须重写equals和hashCode方法,确保JPA能正确识别主键:

import java.util.Objects;

@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ApibsPK implements Serializable {
    private int cntbtch;
    private int cntitem;
    private int cntpaym;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ApibsPK apibsPK = (ApibsPK) o;
        return cntbtch == apibsPK.cntbtch && cntitem == apibsPK.cntitem && cntpaym == apibsPK.cntpaym;
    }

    @Override
    public int hashCode() {
        return Objects.hash(cntbtch, cntitem, cntpaym);
    }
}

2. 正确使用实体类的Builder创建对象

在@IdClass模式下,实体类本身持有所有主键字段,无需单独传入ApibsPK对象。直接通过Builder设置三个主键字段即可:

Apibs apibs = Apibs.builder()
        .cntbtch(1)
        .cntitem(2)
        .cntpaym(3)
        .audtdate(20240520)
        .audttime(123456)
        .audtuser("ADMIN")
        .audtorg("ORG001")
        .datedue(20240620)
        .build();

// 执行保存操作
apibsRepository.save(apibs);

3. 排查保存操作的调用方式

确保调用save方法时传入的是完整的Apibs对象,而非单个主键字段值(比如误传Integer类型的单个主键),这是导致错误提示中“Supplied id had wrong type”的常见原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 22:57:43