1. 概述

本文将重点介绍如何修复Hibernate中常见的错误:DuplicateMappingException: Column is duplicated in mapping for entity

我们将首先分析该异常的根本原因,然后通过实际案例复现问题,最后提供解决方案。

2. 理解DuplicateMappingException

在深入解决方案前,我们先来理解这个异常的本质。

DuplicateMappingExceptionMappingException的子类,专门用于处理对象关系映射中的重复定义问题。

⚠️ 核心原因:当同一个数据库列在实体类中被多次映射时,Hibernate会抛出此异常。此时Hibernate无法确定如何处理这种重复映射。

3. 复现DuplicateMappingException

了解了异常成因后,我们通过实际代码来复现这个问题。

考虑以下Person实体类:

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

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

    @Column(name = "first_name") // 踩坑点!
    private String lastName;

    // 标准getter/setter方法
}

这个实体类定义了三个字段:

  • id:主键标识
  • firstName:名字
  • lastName:姓氏

关键问题在于:@Column注解将firstNamelastName都映射到了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抛出DuplicateMappingException,因为firstNamelastName字段都映射到了同一列。

4. 修复异常

解决方案很简单:确保每个字段映射到唯一的数据库列

修改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的成因和解决方案:

  • 问题根源:同一列被多个实体字段重复映射
  • 解决方案:为每个字段指定唯一的列名映射

完整示例代码可在GitHub仓库获取:hibernate-exceptions-2


原始标题:Fixing Hibernate’s DuplicateMappingException When a Column Is Duplicated for an Entity | Baeldung