Core Java

Hibernate Fix DuplicateMappingException

1. Introduction

To fix DuplicateMappingException requires that a column only maps to a single field. The org.hibernate.DuplicateMappingException is a runtime exception and is raised whenever a duplicate for a certain type occurs. In this example, I will create a Spring Data JPA project to demonstrate five entities that throw the duplicate column exception and how to fix it.

  • Duplicate columns mapping within an entity.
  • Duplicate columns mapping with @JoinColumn.
  • Duplicate columns mapping with @Embedded.
  • Duplicate columns mapping with @MappedSuperclass.
  • Duplicate columns with two entities mapped to the same table.

2. Setup

In this step, I will create a gradle project with H2, Spring Data JPA, and Lombok libraries.

build.gradle

plugins {
	id 'java'
	id 'org.springframework.boot' version '3.5.0'
	id 'io.spring.dependency-management' version '1.1.7'
}

group = 'org.zheng.demo'
version = '0.0.1-SNAPSHOT'

java {
	toolchain {
		languageVersion = JavaLanguageVersion.of(17)
	}
}

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	compileOnly 'org.projectlombok:lombok'
	runtimeOnly 'com.h2database:h2'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

tasks.named('test') {
	useJUnitPlatform()
}

2.1 Application.properties

In this step, I will update the application.properties to configure the log levels.

application.properties

spring.application.name=HibernateMappingExceptionDemo

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

logging.level.org.hibernate=DEBUG
logging.level.org.hibernate.orm.mapping=TRACE

logging.level.org.springframework.context=DEBUG
logging.level.org.springframework.boot.autoconfigure.orm.jpa=DEBUG

2.2 Address

In this step, I will create the Address.java as an embeddable object.

Address.java

package org.jcg.zheng.entity;

import jakarta.persistence.Embeddable;
import lombok.Data;

@Embeddable
@Data
public class Address {

	private String line1;
	private String line2;
	private String city;
	private String state;
	private String zipCode;

}

2.3 BaseEntity

In this step, I will create the BaseEntity.java as a base entity.

BaseEntity.java

package org.jcg.zheng.entity;

import java.time.LocalDateTime;

import jakarta.persistence.Column;
import jakarta.persistence.MappedSuperclass;

@MappedSuperclass
public class BaseEntity {
	
	@Column(name="created_at")
	private LocalDateTime createdAt;

}

3. Duplicate Column Mapping

In this step, I will demonstrate that Spring Data JPA throws a MappingException when a column is mapped to multiple fields of an entity. We can fix it by removing the extra fields or remapping to a different column.

3.1 Duplicate Column Mapping

In this step, I will create a DemoEntity.java that annotates with @Table and maps to the T_DEMO table. It maps both firstName and lastName to the same “name” column, so it triggers the HibernateMappingException during the Spring context creation.

DemoEntity

package org.jcg.zheng.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Data;

@Entity
@Table(name = "T_DEMO")
@Data
public class DemoEntity {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;

	private Integer age;

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

	@Column(name = "name")
	private String lastName;

}
  • Line 22, 25: two fields map to the same column: name and cause the DuplicateMappingException. We can remove or remap to a different column.

3.2 DemoEntityRepo

In this step, I will create a DemoEntityRepo.java that annotates with @Repository and extends from JpaRepository.

DemoEntityRepo.java

package org.jcg.zheng.repo;

import org.jcg.zheng.entity.DemoEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface DemoEntityRepo extends JpaRepository<DemoEntity, Integer> {

}

3.3 DemoEntityRepoTest

In this step, I will create a DemoEntityRepoTest.java that annotates with @SpringBootTest and save a DemoEntity.

DemoEntityRepoTest.java

package org.jcg.zheng.repo;

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;

import org.jcg.zheng.entity.DemoEntity;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class DemoEntityRepoTest {

	@Autowired
	private DemoEntityRepo testRepo;
	private DemoEntity demoEntity = new DemoEntity();

	@Test
	void testSave() {
		assertNull(demoEntity.getId());
		demoEntity.setFirstName("Mary");

		testRepo.save(demoEntity);
		assertNotNull(demoEntity.getId());
	}

}

3.4 Caught DuplicateMappingException

In this step, I will execute DemoEntityRepoTest.java and capture the exception details.

DemoEntityRepoTest Output

Caused by: org.hibernate.MappingException: Column 'name' is duplicated in mapping for entity 'org.jcg.zheng.entity.DemoEntity' (use '@Column(insertable=false, updatable=false)' when mapping multiple properties to the same column)
	
  • The error message states that the MappingException is caused by "Column 'name' is duplicated in mapping for entity 'org.jcg.zheng.entity.DemoEntity'". We can fix it by configuring insertable and updable attributes with the false value. The common solution is to remove or remap the duplicate fields outlined in step 3.1.

3.5 Fix DuplicateMappingException

In this step, I will update DemoEntity.java and correct the “name” column to map to “firstName“. After that, run the same DemoEntityRepoTest and confirm the test passed.

DemoEntityRepoTest Output

2025-06-14T14:07:36.958-05:00 DEBUG 27080 --- [HibernateMappingExceptionDemo] [           main] org.hibernate.SQL                        : 
    insert 
    into
        t_demo
        (age, first_name, name, id) 
    values
        (?, ?, ?, default)
Hibernate: 
    insert 
    into
        t_demo
        (age, first_name, name, id) 
    values
        (?, ?, ?, default)
2025

4. Mapping a Column to Many Fields Within @Embedded

This step is similar to step 3. The difference is the mapped field is a part of @Embedded object.

4.1 Map the Same Column Many Times with @Embedded Object

In this step, I will create a DemoEmbedEntity.java that annotates with @Table and maps to the T_DEMO_EMBED table. The state column is mapped to both address and state, so it triggers the HibernateMappingException during the Spring context creation.

DemoEntity

package org.jcg.zheng.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Data;

@Entity
@Table(name = "T_DEMO_EMBED")
@Data
public class DemoEmbedEntity {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;

	private String name;

	@Embedded
	private Address address;

	/* MappingException: Column 'state' is duplicated in mapping for entity */
	@Column(name = "state")
	private String state;

}
  • Line 24, 27: the state is mapped twice, one is defined in Address outlined in step 2.2, the other is the state field.

4.2 DemoEmbedEntityRepo

In this step, I will create a DemoEmbedEntityRepo.java that annotates with @Repository and extends from JpaRepository.

DemoEmbedEntityRepo.java

package org.jcg.zheng.repo;

import org.jcg.zheng.entity.DemoEmbedEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface DemoEmbedEntityRepo extends JpaRepository<DemoEmbedEntity, Integer> {

}

4.3 DemoEmbedEntityRepoTest

In this step, I will create a DemoEmbedEntityRepoTest.java that annotates with @SpringBootTest and save a DemoEmbedEntity.

DemoEmbedEntityRepoTest.java

package org.jcg.zheng.repo;

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;

import org.jcg.zheng.entity.DemoEmbedEntity;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class DemoEmbedEntityRepoTest {

	@Autowired
	private DemoEmbedEntityRepo testRepo;
	private DemoEmbedEntity demoEntity = new DemoEmbedEntity();

	@Test
	void testSave() {
		assertNull(demoEntity.getId());
		demoEntity.setName("Mary");

		testRepo.save(demoEntity);
		assertNotNull(demoEntity.getId());
	}

}

4.4 Caught DuplicateMappingException

In this step, I will execute DemoEmbedEntityRepoTest.java and capture the exception details.

DemoEmbedEntityRepoTest Output

Caused by: org.hibernate.MappingException: Column 'state' is duplicated in mapping for entity 'org.jcg.zheng.entity.DemoEmbedEntity' (use '@Column(insertable=false, updatable=false)' when mapping multiple properties to the same column)

4.5 Fix DuplicateMappingException

In this step, I will update DemoEmbedEntity.java and remove the “state“. After that, run the same DemoEmbedEntityRepoTest and confirm the test passed.

DemoEmbedEntityRepoTest Output

2025-06-14T14:22:27.142-05:00 DEBUG 15112 --- [HibernateMappingExceptionDemo] [           main] org.hibernate.SQL                        : 
    insert 
    into
        t_demo_embed
        (city, line1, line2, state, zip_code, name, id) 
    values
        (?, ?, ?, ?, ?, ?, default)
Hibernate: 
    insert 
    into
        t_demo_embed
        (city, line1, line2, state, zip_code, name, id) 
    values
        (?, ?, ?, ?, ?, ?, default)

5. JoinColumn With Same Name

5.1 Map the Same Column via @JoinColumn

In this step, I will create a DemoJoinEntity.java that annotates with @Table and maps to the T_DEMO_JOIN table. The foreign key “demo_id” column is mapped to both demo and demo_id, so it triggers the HibernateMappingException during the Spring context creation.

DemoJoinEntity

package org.jcg.zheng.entity;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.Data;

@Entity
@Table(name = "T_DEMO_JOIN")
@Data
public class DemoJoinEntity {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;

	private String name;

	@OneToOne(cascade = CascadeType.PERSIST)
	@JoinColumn(name = "demo_id")
	private DemoEntity demo;

	/* MappingException Column 'demo_id' is duplicated in mapping for entity */
	@JoinColumn(name = "demo_id")
	private Integer demo_id;

}
  • Line 25, 29: the “demo_id” column is mapped to two fields and triggers the DuplicateMappingException.

5.2 DemoJoinEntityRepo

In this step, I will create a DemoJoinEntityRepo.java that annotates with @Repository and extends from JpaRepository.

DemoJoinEntityRepo.java

package org.jcg.zheng.repo;

import org.jcg.zheng.entity.DemoJoinEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface DemoJoinEntityRepo extends JpaRepository<DemoJoinEntity, Integer> {

}

5.3 DemoJoinEntityRepoTest

In this step, I will create a DemoJoinEntityRepoTest.java that annotates with @SpringBootTest and save a DemoEntity.

DemoJoinEntityRepoTest.java

package org.jcg.zheng.repo;

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;

import org.jcg.zheng.entity.DemoJoinEntity;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class DemoJoinEntityRepoTest {

	@Autowired
	private DemoJoinEntityRepo testRepo;
	private DemoJoinEntity demoEntity = new DemoJoinEntity();

	@Test
	void testSave() {
		assertNull(demoEntity.getId());
		demoEntity.setName("Mary");

		testRepo.save(demoEntity);
		assertNotNull(demoEntity.getId());
	}
}

5.4 Caught DuplicateMappingException

In this step, I will execute DemoJoinEntityRepoTest.java and capture the exception details.

DemoJoinEntityRepoTest Output

Caused by: org.hibernate.MappingException: Column 'demo_id' is duplicated in mapping for entity 'org.jcg.zheng.entity.DemoJoinEntity' (use '@Column(insertable=false, updatable=false)' when mapping multiple properties to the same column)

5.5 Fix DuplicateMappingException

In this step, I will update DemoJoinEntity.java and remove the “demo_id“. After that, run the same DemoJoinEntityRepoTest and confirm the test passed.

DemoJoinEntityRepoTest Output

2025-06-14T14:33:18.991-05:00 DEBUG 11332 --- [HibernateMappingExceptionDemo] [           main] org.hibernate.SQL                        : 
    insert 
    into
        t_demo_join
        (demo_id, name, id) 
    values
        (?, ?, default)
Hibernate: 
    insert 
    into
        t_demo_join
        (demo_id, name, id) 
    values
        (?, ?, default)

6. Inheritance Duplicate Mapping

6.1 The Same Column Map to Both Parent and Child Entities

In this step, I will create a DemoChildEntity.java that annotates with @Table and maps to the T_DEMO_CHILD table. The created_at column is mapped in both BaseEntity and DemoChildEntity, so it triggers the HibernateMappingException during the Spring context creation.

DemoChildEntity

package org.jcg.zheng.entity;

import java.time.LocalDateTime;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Data;

@Entity
@Table(name = "T_DEMO_CHILD")
@Data
public class DemoChildEntity extends BaseEntity {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;

	private String name;

	/*
	 * MappingException: Column 'created_at' is duplicated in mapping for entity
	 */
	@Column(name="created_at") 
	private LocalDateTime createdDateTime;

}
  • Line 27: the “created_at” column is mapped in BaseEntity outlined in step 2.3.

6.2 DemoChildEntityRepo

In this step, I will create a DemoChildEntityRepo.java that annotates with @Repository and extends from JpaRepository.

DemoChildEntityRepo.java

package org.jcg.zheng.repo;

import org.jcg.zheng.entity.DemoChildEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface DemoChildEntityRepo extends JpaRepository<DemoChildEntity, Integer> {

}

6.3 DemoChildEntityRepoTest

In this step, I will create a DemoChildEntityRepoTest.java that annotates with @SpringBootTest and save a DemoEntity.

DemoChildEntityRepoTest.java

package org.jcg.zheng.repo;

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;

import org.jcg.zheng.entity.DemoChildEntity;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class DemoChildEntityRepoTest {

	@Autowired
	private DemoChildEntityRepo testRepo;
	private DemoChildEntity demoEntity = new DemoChildEntity();

	@Test
	void testSave() {
		assertNull(demoEntity.getId());
		demoEntity.setName("Mary");

		testRepo.save(demoEntity);
		assertNotNull(demoEntity.getId());
	}

}

6.4 Caught DuplicateMappingException

In this step, I will execute DemoChildEntityRepoTest.java and capture the exception details.

DemoChildEntityRepoTest Output

Caused by: org.hibernate.MappingException: Column 'created_at' is duplicated in mapping for entity 'org.jcg.zheng.entity.DemoChildEntity' (use '@Column(insertable=false, updatable=false)' when mapping multiple properties to the same column)	

6.5 Fix DuplicateMappingException

In this step, I will update DemoChildEntity.java and remove “createdDateTime“. After that, run the same DemoChildEntityRepoTest and confirm the test passed.

DemoEntityRepoTest Output

2025-06-14T14:55:21.421-05:00 DEBUG 22324 --- [HibernateMappingExceptionDemo] [           main] org.hibernate.SQL                        : 
    insert 
    into
        t_demo_child
        (created_at, name, id) 
    values
        (?, ?, default)
Hibernate: 
    insert 
    into
        t_demo_child
        (created_at, name, id) 
    values
        (?, ?, default)

7. Mapping Table with Many Entities

When more than one @Entity classes map to the same table and there is conflicting column mapping, then the duplicate mapping exception is thrown.

7.1 Map Another Entity for T_DEMO table

In this step, I will create a DemoDuplicateEntity.java that annotates with @Table and maps to the T_DEMO table as the DemoEntity.java outlined in step 3. It maps both age and name to the same “age” column, so it triggers the HibernateMappingException during the Spring context creation.

DemoDuplicateEntity

package org.jcg.zheng.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Data;

@Entity
@Table(name = "T_DEMO")
@Data
public class DemoDuplicateEntity {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;

	private Integer age;

	private String firstName;

	// MappingException: Column 'age' is duplicated in mapping for entity
	@Column(name="age")
	private String name;

}
  • Line 20, 25: both fields map to the same “age” column. Need to remove one of them.

7.2 DemoDuplicateEntityRepo

In this step, I will create a DemoDuplicateEntityRepo.java that annotates with @Repository and extends from JpaRepository.

DemoDuplicateEntityRepo.java

package org.jcg.zheng.repo;

import org.jcg.zheng.entity.DemoDuplicateEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface DemoDuplicateEntityRepo extends JpaRepository<DemoDuplicateEntity, Integer> {

}

7.3 DemoDuplicateEntityRepoTest

In this step, I will create a DemoEntityRepoTest.java that annotates with @SpringBootTest and save a DemoEntity.

DemoEntityRepoTest.java

package org.jcg.zheng.repo;

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;

import org.jcg.zheng.entity.DemoDuplicateEntity;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class DemoDuplicateEntityRepoTest {

	@Autowired
	private DemoDuplicateEntityRepo testRepo;
	private DemoDuplicateEntity demoEntity = new DemoDuplicateEntity();

	@Test
	void testSave() {
		assertNull(demoEntity.getId());
		demoEntity.setName("Mary");

		testRepo.save(demoEntity);
		assertNotNull(demoEntity.getId());
	}
}

7.4 Caught DuplicateMappingException

In this step, I will execute DemoDuplicateEntityRepoTest.java and capture the exception details.

DemoEntityRepoTest Output

Caused by: org.hibernate.MappingException: Column 'age' is duplicated in mapping for entity 'org.jcg.zheng.entity.DemoDuplicateEntity' (use '@Column(insertable=false, updatable=false)' when mapping multiple properties to the same column)

7.5 Fix DuplicateMappingException

In this step, I will update DemoDuplicateEntity.java and change the “age” column to only map to “age“. After that, run the same DemoDuplicateEntityRepoTest and confirm the test passed.

DemoDuplicateEntityRepoTest Output

2025-06-14T18:12:07.654-05:00 DEBUG 29732 --- [HibernateMappingExceptionDemo] [           main] org.hibernate.SQL                        : 
    insert 
    into
        t_demo
        (age, first_name, name, id) 
    values
        (?, ?, ?, default)
Hibernate: 
    insert 
    into
        t_demo
        (age, first_name, name, id) 
    values
        (?, ?, ?, default)

Run the Junit tests and capture the results after removing duplicate columns.

fix duplicateMappingException
Figure 1 Test Results

8. Conclusion

In this example, I showed that Hibernate MappingException is thrown during the Spring context initialization when there is a column mapped to many fields in an entity. The duplicate fields can be found in the entity class, base class, embed object, or joined column. To fix it, we can remove the duplicate field or re-map it to a different column based on the detail message of the MappingException.

9. Download

This was an example of a Spring boot JPA gradle project that demonstrated a fix for DuplicateMappingException.

Download
You can download the full source code of this example here: Hibernate Fix DuplicateMappingException

Mary Zheng

Mary graduated from the Mechanical Engineering department at ShangHai JiaoTong University. She also holds a Master degree in Computer Science from Webster University. During her studies she has been involved with a large number of projects ranging from programming and software engineering. She worked as a lead Software Engineer where she led and worked with others to design, implement, and monitor the software solution.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button