You need to enable JavaScript to run this app. Spring Data JDBC聚合根含多个同类型值对象查询结果异常问题
优惠活动
大模型
产品
解决方案
定价
更多

Spring Data JDBC聚合根含多个同类型值对象查询结果异常问题

Spring Data JDBC多同类型关联属性查询返回重复记录问题解决方案

问题根本原因

你的address表仅存储了关联的customer外键,没有字段标识该address记录对应Customer聚合中的address1还是address2属性。Spring Data JDBC查询时会将同一个customer关联的所有address记录做笛卡尔积拼接,2条address记录会生成2*2=4条结果集,映射时就产生了4个ID相同的Customer实例,按ID查询时就会抛出结果大小不符合预期的异常。
当Customer仅包含1个Address属性时,不需要区分属性归属,不会产生笛卡尔积,因此功能正常。

修复方案

方案一:保留address独立表(符合原有设计)

  1. 改造address表结构,新增用于标识属性归属的字段:
ALTER TABLE "address" ADD COLUMN "address_property" VARCHAR(255) NOT NULL;
  1. 在Customer类的两个Address属性上添加@MappedCollection注解,指定关联规则:
import org.springframework.data.relational.core.mapping.MappedCollection;

@Data
@Builder
@AllArgsConstructor
class Customer {
    @Id Long id;
    String name;
    @MappedCollection(keyColumn = "address_property", idColumn = "customer")
    Address address1;
    @MappedCollection(keyColumn = "address_property", idColumn = "customer")
    Address address2;
}

Spring Data JDBC会自动将属性名address1、address2作为key值存入address_property字段,查询时也会根据该字段区分address对应的属性,避免笛卡尔积问题。

方案二:内嵌Address到Customer表

如果不需要独立存储address,可将Address改为嵌入式对象,无需单独建address表:

  1. 给Address类添加@Embeddable注解:
import jakarta.persistence.Embeddable;

@Data
@Builder
@AllArgsConstructor
@Embeddable
class Address {
    String city;
}
  1. 改造customer表结构,新增两个address对应的city字段:
ALTER TABLE "customer" ADD COLUMN "address1_city" VARCHAR(255) NOT NULL;
ALTER TABLE "customer" ADD COLUMN "address2_city" VARCHAR(255) NOT NULL;

删除原有address表即可,查询时不需要join操作,不会出现重复记录问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 07:15:04