加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – Hibernate 4:持久化InheritanceType.JOINED标识符列值

发布时间:2020-12-14 05:25:44 所属栏目:Java 来源:网络整理
导读:我有一个简单的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,bi
我有一个简单的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,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
{
    ...
}

后一类应被映射到文档的标识符列值“外部”.当通过EntityManager发现实体时,识别符被正确地返回,实际上是因为我的测试数据的识别符被正确插入数据块.

现在我使用以下代码通过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不会将“外部”鉴别器值插入到“文档”表的标识符列中.

过去有一些问题,见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,但它不起作用(参见Document Class中的@DiscriminatorOptions).

如何让Hibernate 4使用原始注释插入标识符?

注意:我不想将discriminator列映射为常规列.

解决方法

首先,这个问题是 Discriminator in InheritanceType.JOINED的重复.

看起来像JOINED继承中的持久性鉴别器值不是JPA规范所要求的.这是我通过电子邮件从JPA专家组的成员收到的内容:

The spec does not require an implementation to use discriminator columns to implement JOINED inheritance,however,the assumption is that if @DiscriminatorColumn is specified then it would be used,i.e. the values would be written out. We do not explicitly state that if a @DiscriminatorColumn is specified in the code it must be used,just like we don’t explicitly state that if a @Column or @JoinColumn is specified the values must be stored in the table,but there is only so much that we can or should specify. At the lowest level,certain laws of physics and reason are just assumed.

手头的问题一直是Hibernate一段时间的问题,请看这里:

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

拒绝评论:

EJB3 does NOT require use of discriminators with JOINED mapping strategies. It is allowed for inferior implementations of the JOINED mapping strategy which require a discriminator. Hibernate does not need a discriminator because Hibernate is better than these other inferior implementations.

最终只有SINGLE_TABLE策略需要一个鉴别器列,JOINED可以实现没有. Hibernate当前的问题是,当使用@DiscriminatorColumn映射的JOINED继承中持久化子实体时,即使JPA规范建议在JOINED中使用鉴别符时,仍然会持久标识符值,因此它将导致不一致的数据.在RFE中查看更多内容:

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读