开发者

How to get the DiscriminatorValue at run time

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 ApplicationProcess is of DiscriminatorValue AP or APS. Since this is automatically handled by jpa, I have no way of getting this value.

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.getApType().equals("AP");


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

public class ApplicationProcess { 

    ...

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

}


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


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 (...)

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

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.


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

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


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

private String theApType;

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

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


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 discriminatorType annotations (Integer is the default for union and join strategies). This solution can be used for SINGLE_TABLE too, if you add such case; or you can use the other solutions mentioned here.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜