一尘不染

Hibernate4:保留InheritanceType.JOINED鉴别符列值

hibernate

我有一个简单的JOINED文件层次结构:

CREATE TABLE Documents
(
  id INTEGER NOT NULL,
  discriminator ENUM('official','individual','external') NOT NULL,
  file_name VARCHAR(200) NOT NULL,
  PRIMARY KEY (id)
);

CREATE SystemDocuments
(
  id INTEGER NOT NULL,
  binary_data BLOB NOT NULL,
  PRIMARY KEY (id),
  FOREIGN KEY (id) REFERENCES Documents (id)
);

CREATE ExternalDocuments
(
  id INTEGER NOT NULL,
  PRIMARY KEY (id),
  FOREIGN KEY (id) REFERENCES SystemDocuments (id)
);

如您所见,所有子表所做的就是共享Documents表中的相同ID。除此之外,SystemDocuments还会添加一binary_data列,并且ExternalDocuments不会添加任何新属性。(还要注意,在层次结构中还有两个其他具体的子表,由'official'和表示'individual'不相关。)

这是上述表的映射:

Document.java

@Entity
@Table(name = "Documents")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "discriminator", discriminatorType = DiscriminatorType.STRING)
//@DiscriminatorOptions(force = true) // <-- Hibernate 4-specific annotation not inserting discriminator values
public abstract class Document implements Serializable
{
    @Id
    @Column
    protected Integer id;

    @Column(name = "file_name")
    protected String fileName;

    ...
}

SystemDocument.java

@Entity
@Table(name = "SystemDocuments")
public abstract class SystemDocument extends Document
{
    @Lob
    @Column(name = "binary_data")
    protected byte[] binaryData;

    ...
}

ExternalDocument.java

@Entity
@Table(name = "ExternalDocuments")
@DiscriminatorValue(value = "external")
public class ExternalDocument extends SystemDocument
{
    ...
}

后者应映射到Documents的discriminator列value
'external'。当通过EntityManager.find查找实体时,鉴别符会正确返回,这实际上是因为我的测试数据的鉴别符已正确插入到数据库中。

现在,我使用以下代码通过JPA和文件上传器将新文档/文件插入系统:

...

UploadedFile uf = event.getUploadedFile();

// set ID, file name, and binary data
ExternalDocument detachedExternalDocument =
    new ExternalDocument(1234567, uf.getName(), uf.getData());

docService.create(detachedExternalDocument);

但是,在检查数据库时,我可以看到Hibernate 没有
'external'鉴别符值插入到Documents表的discriminator列中。

已经有问题,这个在过去,看到https://hibernate.onjira.com/browse/ANN-140以及最近对Hibernate
4
https://hibernate.onjira.com/browse/HHH-4358,因此机会它应该以这种方式工作吗?

然后,我在当前的Hibernate 4
API文档中找到了http://docs.jboss.org/hibernate/core/4.0/javadocs/org/hibernate/annotations/DiscriminatorOptions.html,但它不起作用(请参阅文档类)。

我如何让Hibernate 4 使用原始注释 插入区分

注意 :我不想将鉴别符列映射为常规列。


阅读 239

收藏
2020-06-20

共1个答案

一尘不染

首先,这个问题是InheritanceType.JOINED中Discriminator的副本。

好像正在联接坚持继承鉴别器值, 要求JPA规范。这是我通过电子邮件从JPA专家组的成员那里收到的信息:

该规范不需要使用区分符列来实现JOINED继承的实现,但是,假设是如果指定了@DiscriminatorColumn,则将使用它,即将值写出。我们没有明确声明如果在代码中指定了@DiscriminatorColumn,则必须使用,就像我们没有明确声明如果指定了@Column或@JoinColumn一样,值必须存储在表中,但是存在我们只能或应该指定这么多。在最低级别上,仅假设了某些物理定律和推理。

Hibernate面临的问题已经有一段时间了,请参见此处:

https://hibernate.atlassian.net/browse/ANN-140

拒绝评论:

EJB3不需要将识别符与JOINED映射策略一起使用。它 允许
用于需要鉴别的JOINED映射策略的劣质实现。Hibernate不需要区分符,因为Hibernate比其他劣等实现要好。

最后,只有SINGLE_TABLE策略需要一个鉴别符列,而无需实现JOINED 即可
。当前,Hibernate的问题在于,即使在将鉴别符与JOINED一起使用的情况下,即使JPA规范建议保留鉴别符值,当在使用@DiscriminatorColumn映射的JOINED继承中保留子实体时,它也会导致数据不一致。在RFE中查看更多信息:

https://hibernate.atlassian.net/browse/HHH-6911

2020-06-20