JPA插入时重复列报错:多列作为主键与外键的问题
JPA插入时重复生成
active列导致参数未赋值的解决方法 在使用JPA操作分区表时,插入数据出现SQL报错,提示参数未赋值,生成的INSERT语句里active列重复出现。数据库表payment_item以active作为分区键,同时它是主键和外键的组成部分,无法移除。
问题根源
你的PaymentItemEntity中,同一个数据库列active被映射了两次:
- 一次是作为实体的
@Id字段 - 另一次是在
@ManyToOne关联的@JoinColumn中指定的关联列
JPA会将这两个映射视为独立字段,生成INSERT语句时会重复写入active列,而关联映射的那列未赋值,最终导致参数缺失报错。
解决方案
修改关联映射的@JoinColumn,将active列标记为不可插入、不可更新,让JPA只通过主键字段维护该列的值:
修正后的实体类代码
@Entity @Table(name = "payment_item") @IdClass(PaymentItemKey.class) public class PaymentItemEntity { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "payment_item_generator") @SequenceGenerator(name = "payment_item_generator", sequenceName = "payment_item_seq", allocationSize = 1) private Long id; @Id private boolean active = true; @ManyToOne @JoinColumns({ @JoinColumn(name = "payment_id", referencedColumnName = "id"), // 关键修改:标记active列不可插入更新 @JoinColumn(name = "active", referencedColumnName = "active", insertable = false, updatable = false) }) private PaymentEntity payment; // 需补充getter/setter、equals、hashCode方法,此处省略 }
补充优化建议
- 确保
PaymentItemKey的字段类型与实体类完全一致,避免潜在类型兼容问题:
public class PaymentItemKey implements Serializable { private Long id; private boolean active = true; // 改为boolean与实体类字段类型统一 // 需补充无参构造、equals、hashCode方法,此处省略 }
- 数据库中
active列的默认值true可保留,但实体类已设置默认值,插入时会优先使用实体类的值,确保与分区规则匹配。
原理说明
通过insertable = false, updatable = false告知JPA:该关联列无需当前实体维护,其值已由主键字段active提供。这样JPA生成SQL时就不会重复添加active列,仅使用主键的active值完成插入操作。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

