将Hibernate实体映射为未知的DiscriminatorValue for InheritanceType.SINGLE_TABLE

时间:2012-06-30 08:24:19

标签: java hibernate jpa

我有一个经典的Hibernate @Inheritance(strategy=InheritanceType.SINGLE_TABLE)@DiscriminatorFormula。它工作正常。但是,数据库中的@DiscriminatorValue大约有500个不同的值,我需要将其中大约30个映射到Java类(子级),其余的映射到父级Java类。

可以将问题建模为Animal类的示例继承。

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorFormula("...")
public class Animal implements Serializable {
  ...
  @Column
  public String getName() { ... }
}

所以我在Java代码中使用@DiscriminatorValue定义了大约30个Animal的子类。当Hibernate为鉴别器找到未知值时,它会抛出WrongClassException。但是,我需要将这些未知的鉴别器值映射到一个实体,最好是Animal类。 (在这种情况下,我只需要使用getName()方法。)

我知道一个解决方案是将SQL CASE放入@DiscriminatorFormula但是我必须说明所有30个已知的鉴别器值(当我需要添加其他值时加上更多)。所以我正在寻找更灵活的解决方案。

P.S。这是遗留代码,因此我无法更改模型。

2 个答案:

答案 0 :(得分:7)

tscho指出了我正确的方向,所以我能够为我的案例找到解决方案。 @DiscriminatorValue评估特殊值@DiscriminatorValue("null")@DiscriminatorValue("not null")。第二个是我的权利。

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorFormula("...")
@DiscriminatorValue("not null")
public class Animal implements Serializable {
  ...
  @Column
  public String getName() { ... }
}

答案 1 :(得分:3)

好消息。我刚刚在新的用户指南中记录了这种行为。这是JIRA问题。

基本上,您有两种选择:

  • @DiscriminatorValue("not null")作为后备策略,当没有明确的鉴别器值映射与底层数据库列值匹配时。
  • 当数据库列值为null时,
  • @DiscriminatorValue("null")。通常,您将此用作基类。

Hibernate blog as well上有一个详细的例子。