如何在运行时获取DiscriminatorValue

时间:2010-06-09 11:34:08

标签: java hibernate inheritance jpa single-table-inheritance

我们有以下课程

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) // optional annotation as this is default
@DiscriminatorColumn(name = "apType", discriminatorType = DiscriminatorType.STRING, length = 255)
@DiscriminatorValue("AP")
public class ApplicationProcess {
}

这个

@Entity
@DiscriminatorValue("APS")
public class ApplicationProcessScheme extends ApplicationProcess {
}

现在我需要在运行时知道ApplicationProcessDiscriminatorValue AP or APS。 由于这是由jpa自动处理的,我无法获得此值。

我们正在调用一个以ApplicationProcess为参数的方法,我想避免使用instanceof来检查它是什么类型。如果我可以做像

这样的事情会更酷
applicationProcess.getApType().equals("AP");

6 个答案:

答案 0 :(得分:39)

您可以将鉴别器映射为只读属性:

public class ApplicationProcess { 

    ...

    @Column(name = "apType", insertable = false, updatable = false)
    private String apType;

}

答案 1 :(得分:36)

我可以想象一些可能有用的案例,但是尽管你需要这个的原因,你可以在你的抽象类方法上创建像

@Transient
public String getDiscriminatorValue(){
    DiscriminatorValue val = this.getClass().getAnnotation( DiscriminatorValue.class );

    return val == null ? null : val.value();
}

答案 2 :(得分:4)

  

我们正在调用一个以ApplicationProcess作为参数的方法,我想避免使用instanceof来检查它是什么类型。如果我可以做(...)

之类的事情会更酷

我认为它不会更酷,这似乎比向我调用instanceOf更糟糕:如果由于某种原因你改变了鉴别器值,它会破坏你的代码。

如果您需要检查类型,请使用instanceOf。使用鉴别器的技巧不会使事情更好,它只会使你的代码不那么健壮。

答案 3 :(得分:0)

您可以使用公式注释。 如果您正在使用Hibernate,则可以根据this link使用以下代码:

private String theApType;

@Formula("apType")
String getTheApType() {
    return theApType;
}

当然,您可以在查询中使用它。

答案 4 :(得分:0)

我已经使用以下解决方案在运行时获取此值,假设您事先不知道什么是继承类型:

SessionFactoryImpl sessionFactory = entityManager.getEntityManagerFactory().unwrap(SessionFactoryImpl.class);
EntityPersister entityPersister = sessionFactory.getEntityPersister( Task.class.getPackage().getName()+"."+param.getValue().get(0) );
int clazz_ = 0;
if(UnionSubclassEntityPersister.class.isInstance(entityPersister)) {
    clazz_ = (Integer) ((UnionSubclassEntityPersister) entityPersister).getDiscriminatorValue();
} else if(JoinedSubclassEntityPersister.class.isInstance(entityPersister)) {
    clazz_ = (Integer) ((JoinedSubclassEntityPersister) entityPersister).getDiscriminatorValue();
}

您应根据clazz_批注更改discriminatorType的类型(整数是联合和联接策略的默认值)。如果添加了这种情况,则该解决方案也可以用于SINGLE_TABLE。或者您可以使用此处提到的其他解决方案。

答案 5 :(得分:0)

我刚遇到这个问题,不得不发表答案。 IMO,这是使用Java反射API的明确案例

DiscriminatorValue annotation = ApplicationProcess.class.getAnnotation(DiscriminatorValue.class);
annotation.getValue().equals("AP");