首页 > 解决方案 > JPA Hibernate InheritanceType.JOINED SchemaManagementException

问题描述

我有一个带有两个子实体类的父实体类。在父类中,三个属性用@ManyToOne 注释,另外五个属性用@Column 注释。

Hibernate 希望使用 @ManyToOne 注释的三个属性(国家、交易所、部门)出现在子数据库表(期货和股票)中。

当 db 表“future”和“stock”中不存在这三个 FK 属性时,将引发以下异常:org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing column [country_id] in table [未来]

知道为什么吗?是否需要将外键列重复/添加到子数据库表中?


@MappedSuperclass
public abstract class BaseEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected int id;
}

父级:仪器

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name="instr_type", discriminatorType = DiscriminatorType.STRING, length = 1)
@Table(name = "instrument")

public class Instrument extends BaseEntity {              

    @Column
    private String symbol;

    @Column
    private String isin;

    @Column
    private String name;

    @Column
    @Enumerated(EnumType.STRING)
    private LiquidEnum liquid;

    @Column
    private boolean active;

    // FK

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "country_id", nullable = false, foreignKey = @ForeignKey(name = "instrument_country_fk"))
    private Country country;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "exchange_id", nullable = false, foreignKey = @ForeignKey(name = "instrument_exchange_fk"))
    private Exchange exchange;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "sector_id", nullable = true, foreignKey = @ForeignKey(name = "instrument_sector_fk"))
    private Sector sector;

    // FK end

    getter / setter
    ...
}

子班:未来

@Entity
@Table(name = "future")
@DiscriminatorValue("F")
@PrimaryKeyJoinColumn(name = "id")
public class Future extends Instrument {

    @Column(name = "expirationdate")
    private LocalDate expirationDate;

    public LocalDate getExpirationDate() {
        return expirationDate;
    }

    public void setExpirationdate(LocalDate expirationDate) {
        this.expirationDate = expirationDate;
    }
}

儿童班:股票

@Entity
@Table(name = "stock")
@DiscriminatorValue("S")
@PrimaryKeyJoinColumn(name = "id")
public class Stock extends Instrument  {

}

标签: hibernatejpadatabase-design

解决方案


我找到了问题的原因:外键对象(国家、交易所、部门)指的是 Stock 实体而不是 Instrument 实体。

当我使用继承策略重构 db 模型时(为实体“Instrument”添加父级),我忘记将 Country、Exchange 和 Sector 中的 @OneToMany 属性重定向到 Instrument 实体。


推荐阅读