如何让@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
相关产品推荐
相关产品推荐

