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

如何让@JoinColumn的columnDefinition忽略关联列的columnDefinition

问题

我编写了如下自引用实体的代码:

@Data
@Builder
@EqualsAndHashCode(callSuper = false)
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table
public class Dictionary implements Persistable<Long> {

    @Id
    @GeneratedValue(generator = "dictionary_gen", strategy = GenerationType.SEQUENCE)
    @SequenceGenerator(name = "dictionary_gen", sequenceName = "dictionary_item_key_seq", allocationSize = 1)
    @Column(name = "item_key", unique = true, updatable = false, columnDefinition = "serial")
    private Long itemKey;

    @Override
    @JsonIgnore
    public Long getId() {
        return itemKey;
    }

    @Override
    @JsonIgnore
    public boolean isNew() {
        return itemKey == null;
    }

    @Nullable
    @ManyToOne
    @JoinColumn(name = "parent_item_key", columnDefinition = "",
            foreignKey = @ForeignKey(name = "dictionary_item_key_fk", value = ConstraintMode.NO_CONSTRAINT))
    @JsonIgnore
    private Dictionary parent;

    @JsonProperty("parentItemKey")
    public Long getParentItemKey() {
        return parent.getItemKey();
    }

    @Column(name = "item_name", length = 120, nullable = false)
    private String itemName;

    @Column(name = "item_description", length = 120, nullable = false)
    private String itemDescription;
}

生成的DDL如下:

create table dictionary (item_key serial not null, 
 item_description varchar(120) not null, 
 item_name varchar(120) not null, 
 parent_item_key serial, 
 primary key (item_key))

可以看到item_key列的serial定义被传递到了parent_item_key列。如何将parent_item_key定义为非serial类型,同时保持其可为空(当字典项无父项时)?我尝试使用@AssociationOverride但无效果。

解决方法

问题根源是Hibernate会默认继承关联实体主键的列定义,你给item_key指定了columnDefinition = "serial",导致外键字段也被设为serial类型。

直接修改@JoinColumn的columnDefinition,给parent_item_key指定正确的非序列类型(比如对应serial的bigint),同时保留nullable特性:

@Nullable
@ManyToOne
@JoinColumn(name = "parent_item_key", columnDefinition = "bigint",
        foreignKey = @ForeignKey(name = "dictionary_item_key_fk", value = ConstraintMode.NO_CONSTRAINT))
@JsonIgnore
private Dictionary parent;

额外说明:其实你可以不用手动给item_key设置columnDefinition = "serial",因为@SequenceGenerator已经配置了对应序列,Hibernate会自动适配PostgreSQL的serial类型。如果坚持保留该配置,务必给关联字段明确指定非serial的列类型,避免被继承。

PostgreSQL中serial是绑定了序列的整数类型,外键只需要匹配对应的基础整数类型(bigint)即可,不需要带序列属性。

内容的提问来源于stack exchange,提问作者cane

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 21:35:19