Table of Contents
Overview
When working with spring data jpa, you probably come across issues like this: You have an entity with an @Embedded attribute. The @Embeddable class has the one property that has the same name as one of your entities’.
You got this error when running the program:
Caused by: org.hibernate.MappingException: Column 'name' is duplicated in mapping for entity 'com.datmt.springdatapostgres.model.Car' (use '@Column(insertable=false, updatable=false)' when mapping multiple properties to the same column) at org.hibernate.mapping.Value.checkColumnDuplication(Value.java:197) at org.hibernate.mapping.MappingHelper.checkPropertyColumnDuplication(MappingHelper.java:249) at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:938) at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:678) at org.hibernate.mapping.RootClass.validate(RootClass.java:273)w
What do you do?
Why Do you have naming conflict with Embedded property
When you use @Embedded type in your entity, the data for the embedded property is store on the same table as your entity. Thus, cases like this:
@Entity public class Car extends Thing { private String name; @Embedded private Engine engine; } @Embeddable public class Engine { private String name; private int power; }
Would result in a naming conflict.
Fix duplicate properties’ name with Embedded type
The fix is quite simple. You can use @AttributeOverride quite effectively. The code above could be rewritten as such:
@Entity public class Car extends Thing { private String name; @Embedded @AttributeOverride(name = "name", column = @Column(name = "engine_name")) private Engine engine; }
Now, I have no problem running this code:
@Test @DisplayName("Test embeddable") void testEmbeddable() { var engine = new Engine("V8", 1000); var car = new Car("BMW", engine); commonRepository.save(car); }
In case you have multiple naming conflicts, you can use @AttributeOverrides
instead.
Imagine both Car and Engine have installedDate and maintenanceDate, the following code would resolve the issue:
@Embedded @AttributeOverrides({ @AttributeOverride(name = "installedDate", column = @Column(name = "engine_installed_date")), @AttributeOverride(name = "maintenanceDate", column = @Column(name = "engine_maintenance_date")) }) private Engine engine;
Conclusion
In this post, I’ve shown you how to resolve naming conflicts when using @Embedded/@Embeddable in spring data jpa.
I build softwares that solve problems. I also love writing/documenting things I learn/want to learn.