質問
次のクラス構造が与えられます:
class Job
{
String description;
Collection<JobHistory> history;
}
class JobHistory
{
Date assignDate;
User jobOwner;
}
class JobOwner
{
String name;
String id;
}
このクラス構造は、JPAを介してdbでアクセスできます。 DAOレイヤーでは、クエリをJPA構文で作成できます。
問題:特定のIDを持ち、 Jobhistory の最後のオーナーである
Job
および JobHistory
エントリのリストが必要ですジョブのcode>(assignDateで順序付け)。非常に複雑に聞こえるかもしれませんが、おそらくもっと簡単です。すべてのジョブと、指定された所有者がジョブの実際の所有者である JobHistory
を教えてください。
更新:わかりやすくするために、クラスの名前を少し変更します。
class Job
{
String description;
Collection<JobOwnerHistory> history;
}
class JobOwnerHistory
{
Date assignDate;
User jobOwner;
}
class JobOwner
{
String name;
String id;
}
すべての Job
には、 assignDate
でソートされた所有者の履歴があります。実際の所有者は、最後に割り当てられたジョブを取得しました(つまり、 MAX(assignDate)
)。すべてのジョブについて、特定のユーザー User
の MAX(assignDate)
を持つ JobOwnerHistory
エントリを検索します。
解決
試してください:
SELECT j, j.history FROM Job j JOIN User u WHERE u.name = :name
EclipseLinkでこれを行う場合、少し変更します。
public List<Job> getAllJobsForUser(String username) {
List<Job> jobs = entityManager
.createQuery("SELECT j FROM Job j JOIN User u WHERE u.name = :name")
.setParameter("name", username)
.setHint(QueryHints.BATCH, "j.history")
.queryForList();
}
違いは?最初のバージョンでは、2つのオブジェクトを返すため、リストまたはオブジェクト配列からそれらを取得する必要がありますが、2番目のバージョンでは、クエリヒントは(おそらく)lazyy 1対多の関係からすべてのジョブ履歴をロードします。
Hibernateにこれと同等のものがあるかどうかわかりません。 Toplink Essentialsはサポートしていません。しかし、それはEclipseLinkの私のお気に入りの機能の1つです。
ああ、明らかに、私がやったようにアドホッククエリの代わりに名前付きクエリを使用できます(おそらくそうすべきです)(ビルド中に検証できるため)。
他のヒント
クエリに対して次の答えが見つかりました:
SELECT j, h FROM Job j JOIN j.history h JOIN h.jobOwner u
WHERE u.name = :name AND
(SELECT MAX(h2.assignDate) FROM Job j2 JOIN j2.history h2
WHERE h2 member of j.history) = h.assignDate
クエリで最も重要な部分は、 MAX(h2.assignDate)
を持つ副選択です。ジョブと所有者履歴の最新のエントリを取得するためです。 。