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

Java JPA OneToMany Map映射报错:Repeated column in mapping for collection

问题原因

你出现Repeated column in mapping for collection报错的核心原因是:@JoinTable的joinColumns属性已经将b_name作为B实体和b_p关联表的外键映射,同时@MapKeyJoinColumns中又再次定义了b_name列,JPA检测到同一个列被两个不同的映射规则控制,因此抛出重复列错误。

此外你的代码和表结构还有几处不匹配的问题:

  • Price实体同时标注了@Entity和@Embeddable,两个注解冲突
  • v_c表的建表语句中字段名和复合主键VCId定义的字段名不匹配
  • b_p表中定义的关联字段是bname,和后续外键引用的b_name不一致
现有结构修复方案

只需要修改B实体中pricing字段的注解,给@MapKeyJoinColumn的b_name字段设置只读属性,避免和joinColumns的映射冲突即可:

@OneToMany(cascade = CascadeType.PERSIST)
@JoinTable(
        name = "b_p",
        joinColumns = @JoinColumn(name = "b_name", referencedColumnName = "name"))
@MapKeyJoinColumns({
        // 标记为不可插入不可更新,避免和joinColumns的b_name冲突
        @MapKeyJoinColumn(name = "b_name", insertable = false, updatable = false),
        @MapKeyJoinColumn(name = "p_c"),
        @MapKeyJoinColumn(name = "c_id")
})
private Map<VC, Price> pricing = new LinkedHashMap<>();

同时修正表结构中字段名不匹配、Price实体注解冲突的问题,即可正常运行。

简化表结构方案(仅保留b、b_p两张表)

你期望的简化结构完全可以通过JPA的@ElementCollection实现,不需要单独维护v_c和price表,结构更简单,查询效率更高:

1. 调整实体定义

  • VCId保持不变,还是作为复合键的@Embeddable类
  • 把Price改成纯嵌入类,移除@Entity、@Id等相关注解:
@Setter
@Getter
@NoArgsConstructor
@Embeddable
public class Price implements Serializable {
  @Column(name = "amount")
  private BigDecimal amount;

  @Column(name = "discount_amount")
  private BigDecimal discountAmount;
}
  • 修改B实体的pricing字段映射:
@ElementCollection
@CollectionTable(
        name = "b_p",
        joinColumns = @JoinColumn(name = "b_name", referencedColumnName = "name")
)
@MapKeyClass(VCId.class)
@AttributeOverrides({
        @AttributeOverride(name = "key.pc", column = @Column(name = "p_c")),
        @AttributeOverride(name = "key.cId", column = @Column(name = "c_id")),
        @AttributeOverride(name = "value.amount", column = @Column(name = "amount")),
        @AttributeOverride(name = "value.discountAmount", column = @Column(name = "discount_amount"))
})
private Map<VCId, Price> pricing = new LinkedHashMap<>();

2. 对应建表语句

CREATE TABLE b
(
    name VARCHAR(100) NOT NULL PRIMARY KEY
    -- 其他业务字段
);

CREATE TABLE b_p
(
    b_name VARCHAR(100) NOT NULL,
    p_c TEXT NOT NULL,
    c_id VARCHAR(50) NOT NULL,
    amount NUMERIC,
    discount_amount NUMERIC DEFAULT 0.00,
    FOREIGN KEY (b_name) REFERENCES b (name) ON DELETE CASCADE,
    PRIMARY KEY (b_name, p_c, c_id)
);

调整后直接传入b_name、p_c、c_id三个字段即可查询到对应的amount和discount_amount,完全满足需求,同时没有多余的表关联,维护成本更低。

内容的提问来源于stack exchange,提问作者mr nooby noob

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 23:09:00