Hibernate 异常 “DuplicateMappingException: Column is duplicated in mapping for entity”

1、概览

本文将带你了解如何处理 Hibernate 异常 “DuplicateMappingException: Column is duplicated in mapping for entity”。

2、理解 DuplicateMappingException

简而言之,DuplicateMappingException 是 MappingException 的子类,专门用于处理重复的对象关系映射错误。

当实体类中多次映射同一列时,会出现 “Column is duplicated in mapping for entity” 的提示信息。这种情况下,Hibernate 无法处理这种重复映射。

3、重现 DuplicateMappingException

了解了导致 Hibernate 抛出 DuplicateMappingException 的原因后,让我们通过实践来复现这个问题。

首先,定义一个 Person 实体类:

@Entity
public class Person {
    @Id
    private int id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "first_name") // 重复定义了 first_name 列
    private String lastName;

    // 省略 Getter/Setter
}

简而言之,一个 person 由 id、firstName 和 lastName 组成。@Entity 注解表明 Person 类是一个 JPA 实体,而 @Id 注解表示主键。此外,@Column 注解将每个实体字段映射到特定的表列。

如你所见,这里故意将 firstName 和 lastName 两个字段都映射到同一列 first_name 上。

现在通过测试用例来重现这个异常:

@Test
void whenDuplicatingColumnMapping_thenThrowMappingException() {
    assertThatThrownBy(() -> {
        session = HibernateUtil.getSessionFactory()
          .openSession();
        session.beginTransaction();

        session.createQuery("FROM Person", Person.class)
          .list();

        session.close();
    }).isInstanceOf(DuplicateMappingException.class)
      .hasMessageContaining("Column 'first_name' is duplicated in mapping for entity");
}

如上所示,Hibernate 抛出了 DupicateMappingException,因为我们使用同一列映射了 firstName 和 lastName 字段。

4、修复异常

如前所述,DuplicateMappingException 的根本原因是将同一列绑定到多个字段。因此,最简单的解决方案是为每个字段映射到唯一的列。

首先,更新 Person 类,将 lastName 属性映射到另一列:

@Column(name = "last_name")  // 修改映射到的数据列
private String lastName;  

现在,创建另一个测试来验证修改是否生效:

@Test
void whenNotDuplicatingColumnMapping_thenCorrect() {
    session = HibernateUtil.getSessionFactory()
      .openSession();
    session.beginTransaction();

    assertThat(session.createQuery("FROM Person", Person.class)
      .list()).isEmpty();

    session.close();
}

不出所料,测试用例成功执行,不再抛出 DuplicateMappingException。

5、总结

本文介绍了了 Hibernate 抛出 “DuplicateMappingException: Column is duplicated in mapping for entity” 异常的原因,以及如何解决这个异常。


Ref:https://www.baeldung.com/hibernate-fix-duplicatemappingexception