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