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

Spring Boot中OneToMany关联返回重复数据且缺失部分数据问题

Kit关联KitImage查询重复且缺失问题排查修复

问题描述

开发Spring Boot项目时,Kit实体与KitImage实体为一对多关联,使用findAll查询Kit时,Kit数据正常,但关联的图片出现异常:图片数量正确,但所有图片均为第一条数据的重复,同时存在部分图片缺失。

错误根源分析

  1. KitImage实体主键设计错误
    原KitImage仅将kitId标注为@Id,同时数据库表用(kit_id, image)作为复合主键。但Hibernate仅识别@Id标注的字段作为实体唯一标识,导致同一个Kit下的所有KitImage被判定为同一实例,最终重复加载第一条数据。另外,byte[]类型的image不适合作为主键,数据库层面无法正确区分不同图片,导致重复图片无法插入,出现缺失。

  2. 数据库迁移脚本错误
    kit_image表中kit_id设置了DEFAULT public.gen_random_uuid(),这完全错误,kit_id应该是关联kits表的外键,而非自动生成新UUID,导致外键关联逻辑混乱。同时复合主键包含image字段,不合理且无法正确工作。

  3. 实体映射逻辑错误
    使用@MapsId但主键仅为kitId,不符合一对多关联的映射规范,导致Hibernate无法正确区分不同的KitImage实例。

修复步骤

1. 修改KitImage实体代码

给KitImage添加独立主键,修正映射逻辑:

@Entity
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
@Table(name = "kit_image")
public class KitImage {
    @Id
    @GeneratedValue
    private UUID id; // 新增独立主键

    @NonNull
    @JsonBackReference
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "kit_id", referencedColumnName = "id")
    Kit kit; // 去掉@MapsId,因为现在有独立主键

    byte[] image;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        KitImage kitImage = (KitImage) o;
        return Objects.equals(id, kitImage.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}

2. 修改数据库迁移脚本

修正kit_image表的结构,添加独立主键,移除错误的默认值和不合理的复合主键:

CREATE TABLE kits
(
    id                uuid DEFAULT public.gen_random_uuid(),
    name              TEXT NOT NULL,
    description       TEXT,
    link              TEXT        NOT NULL,
    quantity          INTEGER     NOT NULL default 0,
    quantity_lent     INTEGER     NOT NULL default 0,
    quantity_reserved INTEGER     NOT NULL default 0,
    pdf               bytea,
    PRIMARY KEY (id)
);

CREATE TABLE kit_image
(
    id                uuid DEFAULT public.gen_random_uuid(),
    kit_id            uuid NOT NULL,
    image             bytea,
    PRIMARY KEY (id),
    FOREIGN KEY (kit_id) REFERENCES kits(id)
);

3. 验证修复

重新执行数据库迁移,启动项目后使用findAll查询Kit,此时关联的KitImage会正确加载所有不同的图片,不会出现重复和缺失问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 15:00:34