如何在运行时获取DiscriminatorValue

我们有以下课程

@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 { } 

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

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

 applicationProcess.getApType().equals("AP"); 

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

 public class ApplicationProcess { ... @Column(name = "apType", insertable = false, updatable = false) private String apType; } 

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

 @Transient public String getDiscriminatorValue(){ DiscriminatorValue val = this.getClass().getAnnotation( DiscriminatorValue.class ); return val == null ? null : val.value(); } 

我们正在调用一个以ApplicationProcess作为参数的方法,我想避免使用instanceof来检查它是什么类型。 如果我可以做像(…)这样的事情会更酷

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

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

您可以使用公式注释。 如果你正在使用Hibernate,你可以根据以下链接使用以下代码:

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

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

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

 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(); } 

您应该根据discriminatorType注释更改clazz_的类型(Integer是union和join策略的默认值)。 如果你添加这样的情况,这个解决方案也可以用于SINGLE_TABLE ; 或者你可以使用这里提到的其他解决方案。