Как получить DiscriminatorValue во время выполнения - PullRequest
23 голосов
/ 09 июня 2010

У нас есть следующие классы

@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");

Ответы [ 6 ]

41 голосов
/ 09 июня 2010

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

public class ApplicationProcess { 

    ...

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

}
37 голосов
/ 26 ноября 2012

Я могу представить несколько случаев, когда это может быть полезно, но, несмотря на причину, по которой вам это нужно, вы можете создать в своем методе абстрактного класса, например

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

    return val == null ? null : val.value();
}
4 голосов
/ 09 июня 2010

Мы вызываем метод, который принимает ApplicationProcess в качестве параметра, и я хочу избежать использования instanceof для проверки того, что это за тип.Было бы круче, если бы я мог сделать что-то вроде (...)

Не думаю, что это будет круче, это кажется хуже, чем звонить мне instanceOf: если по какой-то причине вы меняетезначение дискриминатора, это нарушит ваш код.

Если вам нужно проверить тип, используйте instanceOf.Трюк с использованием дискриминатора не сделает вещи лучше, он просто сделает ваш код менее надежным.

0 голосов
/ 26 февраля 2019

Я только что наткнулся на этот вопрос и должен был опубликовать ответ. ИМО, это очевидный случай использования API отражения Java

DiscriminatorValue annotation = ApplicationProcess.class.getAnnotation(DiscriminatorValue.class);
annotation.getValue().equals("AP");
0 голосов
/ 11 июля 2018

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

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, если вы добавите такой случай; или вы можете использовать другие решения, упомянутые здесь.

0 голосов
/ 09 августа 2017

Вы можете использовать аннотацию формулы.Если вы используете Hibernate, вы можете использовать приведенный ниже код в соответствии с этой ссылкой :

private String theApType;

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

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

...