web-dev-qa-db-ja.com

実行時に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 {
}

ここで、実行時にApplicationProcessDiscriminatorValueAP or APSであるかどうかを知る必要があります。これはjpaによって自動的に処理されるため、この値を取得する方法はありません。

ApplicationProcessをパラメーターとして受け取るメソッドを呼び出していますが、instanceofを使用してタイプを確認することは避けたいと思います。私が次のようなことをすることができればもっと涼しいでしょう

applicationProcess.getApType().equals("AP");
24
Shervin Asgari

識別子を読み取り専用プロパティとしてマップできます。

public class ApplicationProcess { 

    ...

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

}
42
axtavt

役に立つ場合はほとんど想像できませんが、これが必要な理由にもかかわらず、次のような抽象クラスメソッドで作成できます。

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

    return val == null ? null : val.value();
}
39
Wirus

ApplicationProcessをパラメーターとして受け取るメソッドを呼び出していますが、instanceofを使用してそれがどのタイプであるかを確認することは避けたいと思います。私が次のようなことをすることができればもっと涼しいでしょう(...)

かっこいいとは思いません。これは、私にinstanceOfを呼び出すよりも悪いようです。何らかの理由で識別子の値を変更すると、コードが破損します。

タイプを確認する必要がある場合は、instanceOfを使用してください。ディスクリミネーターを使用するトリックは、物事をより良くすることにはなりません。コードの堅牢性が低下するだけです。

4
Pascal Thivent

私はちょうどこの質問に出くわし、答えを投稿しなければなりませんでした。 IMOこれはJavaリフレクションAPIを使用するための明確なケースです

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

継承タイプが何であるかを事前に知らないと仮定して、実行時にこの値を取得するために次のソリューションを使用しました。

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にも使用できます。または、ここに記載されている他のソリューションを使用できます。

0
AngelVel

数式注釈を使用できます。 Hibernateを使用している場合は、 このリンク に従って以下のコードを使用できます。

private String theApType;

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

もちろん、クエリで使用することもできます。

0
user2786531