解决了Hibernate中缺少Discriminator支持和遗留数据库的InheritanceType.JOINED

时间:2013-02-26 01:30:58

标签: hibernate inheritance jpa

在答案herehere中链接的许多回复和各种Hibernate打开的JIRA票证都表示尝试使用InheritanceType.JOINED策略与@DiscriminatorColumn@DiscriminatorValue(如下图所示)不起作用。具体见:https://hibernate.onjira.com/browse/HHH-6911

我的场景是我有一个遗留数据库,它使用标准的“类型”表来区分抽象类型的许多具体类型,并使用参照完整性约束来强制对齐。它似乎需要正确设置抽象类型上的Discriminator字段,以便JPA模型忠实地表示数据库模型的意图。表的简化版如下:

CREATE TABLE CONTACT_INFORMATION (
    CONTACT_INFORMATION_ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    FK_STND_CONTACT_INFO_TYPE_ID INTEGER UNSIGNED NOT NULL,
    -- more here...
    PRIMARY KEY (CONTACT_INFORMATION_ID)
);

CREATE TABLE STND_CONTACT_INFO_TYPE (
    STND_CONTACT_INFO_TYPE_ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    CONTACT_INFO_TYPE_CD CHAR(5) NOT NULL,
    DESCRIPTION_TX VARCHAR(30),
    PRIMARY KEY (STND_CONTACT_INFO_TYPE_ID)
);

CREATE TABLE POSTAL_ADDRESS (
    FK_CONTACT_INFORMATION_ID INTEGER UNSIGNED NOT NULL,
    -- more here...
    PRIMARY KEY (FK_CONTACT_INFORMATION_ID)
);

CREATE TABLE ELECTRONIC_ADDRESS (
    FK_CONTACT_INFORMATION_ID INTEGER UNSIGNED NOT NULL,
    -- more here...
    PRIMARY KEY (FK_CONTACT_INFORMATION_ID)
);

ELECTRONIC_ADDRESSPOSTAL_ADDRESSCONTACT_INFORMATION以及从CONTACT_INFORMATIONSTND_CONTACT_INFORMATION_TYPE的参照完整性约束。

尝试创建允许我使用此模型的JPA注释实体,我想出了以下内容:

@Entity
@Table(name = "CONTACT_INFORMATION")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "FK_STND_CONTACT_INFO_TYPE_ID", discriminatorType = DiscriminatorType.INTEGER)
public abstract class ContactInformation {
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "CONTACT_INFORMATION_ID", unique = true, nullable = false)
    private Integer id;

    @ManyToOne
    @JoinColumn(name = "FK_STND_CONTACT_INFO_TYPE_ID", nullable = false)
    private StandardContractInformationType contactInformationType;
}

@Entity
@Table(name = "STND_CONTACT_INFO_TYPE")
public class StandardContractInformationType  {
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "STND_CONTACT_INFO_TYPE_ID", unique = true, nullable = false)
    private Integer id;

    @Column(name = "CONTACT_INFO_TYPE_CD", nullable = false)
    private String typeCode;

    @Column(name = "DESCRIPTION_TX", length = 30)
    private String description;
}

@Entity
@Table(name = "POSTAL_ADDRESS")
@PrimaryKeyJoinColumn(name = "FK_CONTACT_INFORMATION_ID")
@DiscriminatorValue(value = "1")
public class PostalAddress extends ContactInformation { /*...*/ }

@Entity
@Table(name = "ELECTRONIC_ADDRESS")
@PrimaryKeyJoinColumn(name = "FK_CONTACT_INFORMATION_ID")
@DiscriminatorValue(value = "2")
public class ElectronicAddress extends ContactInformation { /*...*/ }

请注意,即使是这种实现,也需要对与两个子类型的STND_CONTACT_INFO_TYPE表中预先加载的参考数据相对应的“1”和“2”的鉴别器值进行硬编码。

使用此实现,并使用Hibernate 4,为PostalAddress或ElectronicAddress插入记录不会根据先前问题中确定的问题正确设置抽象基表的FK_STND_CONTACT_INFO_TYPE_ID字段。

因此,在所有这些之后,问题是:在尝试忠实于原始数据库模型的意图的同时,有哪些选项可以继续使用漂亮的JPA模型?尝试不同的提供商?查找标准类型信息并在存储库或服务层中添加实施?尝试狠狠眯眼并将其视为一个构图问题而不是继承问题?

0 个答案:

没有答案