【问题标题】:Hibernate 4: persisting InheritanceType.JOINED discriminator column valuesHibernate 4:持久化 InheritanceType.JOINED 鉴别器列值
【发布时间】:2011-12-20 18:51:03
【问题描述】:

我有一个简单的 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
{
    ...
}

后一个类应该映射到文档的鉴别器列值'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 Docs 中找到了http://docs.jboss.org/hibernate/core/4.0/javadocs/org/hibernate/annotations/DiscriminatorOptions.html,但它不起作用(参见 Document 类中的 @DiscriminatorOptions)。

如何让 Hibernate 4使用原始注释插入鉴别器?

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

【问题讨论】:

    标签: java hibernate inheritance jpa discriminator


    【解决方案1】:

    首先,这个问题与Discriminator in InheritanceType.JOINED重复。

    JPA 规范似乎要求在 JOINED 继承中保持鉴别器值。以下是我从 JPA 专家组成员通过电子邮件收到的信息:

    规范不要求实现使用鉴别器列来实现 JOINED 继承,但是,假设如果指定了@DiscriminatorColumn,那么它将被使用,即,值将被写出。我们没有明确声明如果在代码中指定了@DiscriminatorColumn,则必须使用它,就像我们没有明确声明如果指定了@Column 或@JoinColumn,则值必须存储在表中,但是有只有我们可以或应该指定的那么多。在最低层次上,只是假设了某些物理定律和理性。

    手头的问题一直是 Hibernate 的问题,请参阅此处:

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

    拒绝评论:

    EJB3 不需要使用带有 JOINED 映射策略的鉴别器。 允许用于需要鉴别器的 JOINED 映射策略的较差实现。 Hibernate 不需要鉴别器,因为 Hibernate 比这些其他劣质实现要好。

    最后只有 SINGLE_TABLE 策略需要一个鉴别器列,JOINED 可以在没有的情况下实现。 Hibernate 当前的问题是,在使用 @DiscriminatorColumn 映射的 JOINED 继承中持久化子实体时会导致数据不一致,即使 JPA 规范建议在将鉴别器与 JOINED 一起使用时保留鉴别器值。在此处查看更多 RFE:

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

    【讨论】:

    • 最近在该票 (HHH-6911) 上发布了其他 cmets。现在看来,Hibernate(4.2.9、4.3.X)在代码中明确说明时不再忽略鉴别器列。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    • 2015-02-03
    • 2011-03-05
    相关资源
    最近更新 更多