Hibernate 6使用@Any注解时重复列错误的解决方案咨询
Hibernate 6升级中@Any注解的映射冲突问题
环境与原配置
基于H2数据库的Schema:
create table property_holder ( id bigint not null, property_type varchar(255), primary key (id) ); create table string_property ( id bigint not null, "name" varchar(255), "value" varchar(255), primary key (id) ); create table integer_property ( id bigint not null, "name" varchar(255), "value" integer, primary key (id) );
Hibernate 5中正常运行的实体模型:
public interface Property<T> { Long getId(); String getName(); T getValue(); } @Entity @Table(name = "integer_property") public class IntegerProperty implements Property<Integer> { @Id @Column(name = "id") private Long id; @Column(name = "name") private String name; @Column(name = "value") private Integer value; } @Entity @Table(name = "string_property") public class StringProperty implements Property<String> { @Id @Column(name = "id") private Long id; @Column(name = "name") private String name; @Column(name = "value") private String value; } @Entity @Table(name = "property_holder") public class PropertyHolder { @Id @Column(name = "id") private Long id; @Column(name = "property_type") private String propertyType; @Any(metaColumn = @Column(name = "property_type")) @AnyMetaDef(metaType = "string", idType = "long", metaValues = { @MetaValue(value = "S", targetEntity = StringProperty.class), @MetaValue(value = "I", targetEntity = IntegerProperty.class) }) @JoinColumn(name = "id", updatable = false, insertable = false) @Cascade(CascadeType.ALL) private Property property; }
这里将property_holder表的id列同时作为主键和@Any字段property的关联列,在Hibernate 5中可正常运行。
Hibernate 6的适配问题
Hibernate 6弃用了@AnyMetaDef,修改为如下写法:
@Entity @Table(name = "property_holder") public class PropertyHolder { @Id @Column(name = "id") private Long id; @Column(name = "property_type", insertable = false, updatable = false) private String propertyType; @Any @AnyKeyJavaClass(Long.class) @AnyDiscriminator(DiscriminatorType.STRING) @AnyDiscriminatorValues({ @AnyDiscriminatorValue(discriminator = "I", entity = IntegerProperty.class), @AnyDiscriminatorValue(discriminator = "S", entity = StringProperty.class) }) @Column(name = "property_type") @JoinColumn(name = "id") private Property property; }
修改后抛出映射错误:
Caused by: org.hibernate.MappingException: Column 'id' is duplicated in mapping for entity 'com.example.anytest.model.PropertyHolder' (use '@Column(insertable=false, updatable=false)' when mapping multiple properties to the same column) at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:1054) at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:1080) at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:1110) at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:754) at org.hibernate.mapping.RootClass.validate(RootClass.java:288) at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:509) at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:251) at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:431) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1455)
尝试为@JoinColumn添加updatable=false、insertable=false属性无效,唯一可行的方式是修改@JoinColumn的name为其他值(如id2),但这会导致Hibernate生成额外列,而现有数据库无法新增列,因此该方案不可行。
请求解决办法
目前尚未找到适配Hibernate 6且不修改现有数据库结构的解决方案,特此咨询可行的处理方式。
内容的提问来源于stack exchange,提问作者Kaushal Niraula
相关产品推荐
相关产品推荐

