此处和此处的答案中链接的许多响应和各种 Hibernate open JIRA 票证 都表明尝试使用带有and的InheritanceType.JOINED
策略(如下图所示)将不起作用。具体参见:https ://hibernate.onjira.com/browse/HHH-6911 。@DiscriminatorColumn
@DiscriminatorValue
我的场景是我有一个遗留数据库,它使用标准的“类型”表来区分抽象类型的多个具体类型,并具有强制对齐的引用完整性约束。它似乎需要正确设置抽象类型上的鉴别器字段,以便 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)
);
存在 fromELECTRONIC_ADDRESS
和POSTAL_ADDRESS
to的参照完整性约束CONTACT_INFORMATION
,以及一个 from CONTACT_INFORMATION
to STND_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 模型,同时仍然试图忠实于原始数据库模型的意图?尝试不同的提供商?查找标准类型信息并在存储库或服务层中添加强制执行?试着眯起眼睛,把它看作一个组合问题而不是继承问题?