我有一个简单的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'不相关。)
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查找实体时,鉴别符会正确返回,这实际上是因为我的测试数据的鉴别符已正确插入到数据库中。
'external'
现在,我使用以下代码通过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列中。
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 使用原始注释 插入区分 符 ?
注意 :我不想将鉴别符列映射为常规列。
首先,这个问题是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