Hibernate映射异常:关联同主键名表时重复列映射问题求解
当然可以用Hibernate实现这种关联映射!你遇到的org.hibernate.MappingException: Repeated column in mapping for entity异常,主要是两个关键错误导致的,咱们一步步拆解解决:
错误1:关联属性类型不符合规范
@ManyToOne注解标注的属性应该是关联的实体类型(比如Psg或Psr),而不是主键的数值类型(BigDecimal)。你现在把关联属性定义成了BigDecimal,这完全不符合Hibernate关联映射的设计逻辑——关联映射要的是实体对象的关联,不是直接存主键值(那是基本字段映射的事)。
错误2:重复映射同一数据库列
你给两个@JoinColumn都指定了name = "COD_FILEFE_S",这意味着Hibernate会尝试把两个关联属性都绑定到Ctl表的同一个COD_FILEFE_S列上。Hibernate默认不允许同一个实体里多个属性映射到同一张表的同一列,这就是抛出异常的直接原因。
常规业务场景的正确实现
根据大多数业务需求,Ctl表应该有两个独立的外键列,分别关联Psg和Psr的主键COD_FILEFE_S。比如我们给Ctl表的外键列命名为COD_FILEFE_S_PSG和COD_FILEFE_S_PSR,对应的实体类代码如下:
public class Ctl { // 关联Psg实体 @ManyToOne(targetEntity = Psg.class) @JoinColumn( name = "COD_FILEFE_S_PSG", // Ctl表中对应Psg的外键列 referencedColumnName = "COD_FILEFE_S", // Psg表的主键列名 nullable = false ) private Psg psg; // 关联Psr实体 @ManyToOne(targetEntity = Psr.class) @JoinColumn( name = "COD_FILEFE_S_PSR", // Ctl表中对应Psr的外键列 referencedColumnName = "COD_FILEFE_S", // Psr表的主键列名 nullable = false ) private Psr psr; // 这里可以添加Ctl自身的属性,以及所有属性的getter/setter方法 }
特殊业务场景的兼容方案(同一列关联两个表)
如果你的业务逻辑确实要求Ctl表用同一个列同时关联Psg和Psr表(这种场景非常少见,比如同一主键值在两个表中都有对应记录),可以通过insertable和updatable属性来避免映射冲突:
public class Ctl { @ManyToOne(targetEntity = Psg.class) @JoinColumn( name = "COD_FILEFE_S", referencedColumnName = "COD_FILEFE_S", nullable = false, insertable = true, // 允许通过这个属性插入/更新列值 updatable = true ) private Psg psg; @ManyToOne(targetEntity = Psr.class) @JoinColumn( name = "COD_FILEFE_S", referencedColumnName = "COD_FILEFE_S", nullable = false, insertable = false, // 禁止通过这个属性修改列值,仅用于查询关联 updatable = false ) private Psr psr; // 其他属性、getter/setter省略 }
这种配置下,只有psg属性能控制COD_FILEFE_S列的写入操作,psr属性仅用于查询时关联Psr表的数据,不会触发对该列的修改,以此绕过重复列的映射限制。
内容的提问来源于stack exchange,提问作者user1860914

