You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 04:55:32