3

如果我有一个表需要多个列作为鉴别器,那么我唯一的解决方案是使用@DiscriminatorFormula 吗?

我问是因为一些原型设计给了我们一些我无法解释的结果。

失败的原型:最初,我们使用超类上的一个 @DiscriminatorColumn 并在子类上包含第二个 @DiscriminatorColumn 来构建一个 3 深的类层次结构的原型。当然,我们得到了这个警告:

鉴别器列必须在根实体中定义,在子类中将被忽略

我们发现更新有效,但插入无效。所以我们放弃了这个想法。

成功的?原型: 然后我们尝试了以下似乎可行的方法:省略子类上的第二个@DiscriminatorColumn,只在外键上包含@JoinColumn(无论如何我们都需要它)。也许,由于连接是针对不同类型的对象,Hibernate/JPA 似乎能够找出哪个子类是正确的。谁能解释一下?

我们是否应该放弃它并只使用@DiscriminatorFormula 来获得在 2 个鉴别器列上定义的显式关系?

4

2 回答 2

13

DiscriminatorFormula 是 DiscriminatorColumn 的替代方法。您使用其中一个注释超类(将真实表映射为默认值)。使用 DiscriminatorColumn 它会创建一个包含鉴别器值的附加列(默认称为“dtype”)。您将注释放在超类中:

@Entity
@Table(name = "features")
@DiscriminatorColumn
public class Features{
    //valid code
}

DiscriminatorFormula 允许您检查数据库行内容并通过鉴别器值“选择”一个子类。没有创建额外的(“dtype”)列。在主类中,您使用公式注释超类,例如:

@Entity
@Table(name = "features")
@DiscriminatorFormula(
        "CASE WHEN num_value IS NOT NULL THEN 'NUMERIC' " +
        " WHEN txt_value IS NOT NULL THEN 'TEXT' end"
)
public class Features{
    //valid code
}

在 DiscriminatorFormula 中,您只需放置一些纯 SQL 即可完成您需要的操作。

您可以选择这两个选项之一,并且在这两种情况下子类完全相同。在子类中,您指定鉴别器值,例如:

@Entity
@DiscriminatorValue('NUMERIC')
public class NumericFeatures extends Features {

    private Double numValue;

    public Double getNumValue() {
        return numValue;
    }

    public void setNumValue(Double numValue) {
        this.numValue = numValue;
    }

    //valid code
}

在名为“功能”的表中,您有两个列“num_value”和“txt_value”,包含相应的值。使用 DiscriminatorColumn,您将在附加 dtype 列以及“num_value”和“txt_value”列中具有“NUMERIC”或“TEXT”值。

如果您不指定继承策略,则默认为“SINGLE_TYPE”。如果这是您选择的策略,则可以省略以下注释:

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)

无论有没有这个注释,你都会得到一个名为“特征”的表格。

于 2014-11-05T13:57:44.367 回答
1

我将它切换为使用 DiscriminatorFormula,它现在工作得很好。

于 2013-05-08T20:55:35.783 回答