Java 如何在运行时获取 DiscriminatorValue

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3005383/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 15:31:02  来源:igfitidea点击:

How to get the DiscriminatorValue at run time

javahibernateinheritancejpasingle-table-inheritance

提问by Shervin Asgari

We have the following classes

我们有以下课程

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

And this

和这个

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

Now I need to know at runtime if the ApplicationProcessis of DiscriminatorValueAP or APS. Since this is automatically handled by jpa, I have no way of getting this value.

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

We are calling a method that takes an ApplicationProcessas parameter, and I want to avoid using instanceofto check what type it is. Would be cooler if I could do something like

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

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

采纳答案by axtavt

You can map your discriminator as a read-only property:

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

public class ApplicationProcess { 

    ...

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

}

回答by Pascal Thivent

We are calling a method that takes an ApplicationProcess as parameter, and I want to avoid using instanceof to check what type it is. Would be cooler if I could do something like (...)

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

I don't think it would be cooler, this seems worse than calling instanceOfto me: if for whatever reason you change the discriminator value, it would break your code.

我不认为它会更酷,这似乎比打电话instanceOf给我更糟糕:如果您出于某种原因更改了鉴别器值,它会破坏您的代码。

If you need to check the type, use instanceOf. A trick using the discriminator is not going to make things nicer, it would just make your code less robust.

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

回答by Wirus

I can imagine few cases where it might be helpful, but despite the reason why you need this, you could create on your abstract class method like

我可以想象它可能有用的情况很少,但是尽管您需要它的原因,您可以在抽象类方法上创建,例如

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

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

回答by user2786531

You can use Formula Annotation. If you're using Hibernate, you can use the code below according to this link:

您可以使用公式注释。如果您使用的是 Hibernate,则可以根据此链接使用以下代码:

private String theApType;

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

Of course you would be able to use it in your queries.

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

回答by AngelVel

I have used the following solution to get this value at runtime, assuming that you don't know beforehand what is the inheritance type:

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

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

You should change the type of clazz_according to your discriminatorTypeannotations (Integer is the default for union and join strategies). This solution can be used for SINGLE_TABLEtoo, if you add such case; or you can use the other solutions mentioned here.

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

回答by Jan Hruby

I just came across this question and had to post an answer. IMO this is clear cut case for using Java reflection API

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

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