15

私のモデルには、抽象的な「User」クラスと、Applicant、HiringManager、Interviewer などの複数のサブクラスがあります。それらは単一のテーブルにあり、それらすべてを管理する単一の DAO があります。

ユーザー:

@Entity
@Table(name="User")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
    name="role",
    discriminatorType=DiscriminatorType.STRING
)
public abstract class User extends BaseObject implements Identifiable<Long> ...

HiringManager (例):

@Entity
@DiscriminatorValue("HIRING_MANAGER")
public class HiringManager extends User ...

たとえば、部門に関連付けられていないすべての採用担当者を取得したい場合、どうすればよいでしょうか。次のようになると思います。

DetachedCriteria c = DetachedCriteria.forClass(User.class);
c.add(Restrictions.eq("role", "HIRING_MANAGER"));
c.add(Restrictions.isNull("department"));
List<User> results = getHibernateTemplate().findByCriteria(c);

しかし、これを実行すると、Hibernate は「プロパティを解決できませんでした: ロール」と不平を言います (ユーザー クラスには明示的なロール プロパティがないため、これは実際には理にかなっています)

4

2 に答える 2

22

明らかな何かが欠けているかもしれませんが、採用担当者を見つけたいので、HiringManagerサブクラスをクラスとして に渡してみませんCriteriaか?

念のclassため、クエリをサブタイプに制限するために使用できる特別なプロパティがあります。Hibernate リファレンス ドキュメントから:

14.9. where句

...

特別なプロパティclassは、ポリモーフィック永続性の場合にインスタンスの識別子の値にアクセスします。where 句に埋め込まれた Java クラス名は、その識別子の値に変換されます。

from Cat cat where cat.class = DomesticCat

この特別なクラス プロパティを Criteria API でも使用できますが、小さな変更があります。として識別子の値を使用する必要があります。

c.add(Restrictions.eq("class", "HIRING_MANAGER"));

HQL とは異なり、Hibernate は Criteria API で変換を行っていないようです。コードで識別子の値を使用するという考えはあまり好きではありません。別のよりクリーンな方法があるかもしれませんが、私はそれを知りません。しかし、それは機能します。

于 2010-07-07T23:54:13.723 に答える
3

これは、結合されたサブクラスの継承マッピングでも機能することに注意してください。ただし、注意点が1つあります。制限で使用されるクラスは、具象クラスである必要があります。Restrictions.eq("class", Mammal.class);動物<-哺乳類<-猫のようなモデルを持っている場合、すべての哺乳類を取り戻すことはできず、期待することはできません。代わりに、Restrictions。またはすべての既知の具象クラスを使用してブルートフォース攻撃を行う必要がありました(Restrictions.in()を使用すると、クエリの実行時にクラスキャスト例外が発生しました)。

于 2012-07-10T15:36:41.363 に答える