Как получить 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");

5 ответов


вы можете отобразить свой дискриминатор как свойство только для чтения:

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

конечно, вы сможете использовать его в своих запросах.


я использовал следующее решение для получения этого значения во время выполнения, предполагая, что вы заранее не знаете, что такое тип наследования:

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_ в соответствии с вашей!--2--> аннотации (Integer-это значение по умолчанию для стратегий объединения и объединения). Это решение можно использовать для SINGLE_TABLE тоже, если вы добавите такой случай; или вы можете использовать другие решения, упомянутые здесь.