以下のクラスがあります
@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");
識別子を読み取り専用プロパティとしてマップできます。
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
を使用してください。ディスクリミネーターを使用するトリックは、物事をより良くすることにはなりません。コードの堅牢性が低下するだけです。
私はちょうどこの質問に出くわし、答えを投稿しなければなりませんでした。 IMOこれはJavaリフレクションAPIを使用するための明確なケースです
DiscriminatorValue annotation = ApplicationProcess.class.getAnnotation(DiscriminatorValue.class);
annotation.getValue().equals("AP");
継承タイプが何であるかを事前に知らないと仮定して、実行時にこの値を取得するために次のソリューションを使用しました。
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();
}
discriminatorType
アノテーションに従ってclazz_
のタイプを変更する必要があります(整数は結合および結合戦略のデフォルトです)。このようなケースを追加すると、このソリューションはSINGLE_TABLE
にも使用できます。または、ここに記載されている他のソリューションを使用できます。
数式注釈を使用できます。 Hibernateを使用している場合は、 このリンク に従って以下のコードを使用できます。
private String theApType;
@Formula("apType")
String getTheApType() {
return theApType;
}
もちろん、クエリで使用することもできます。