2つのJPAエンティティがあります:
私の目標は、この特定の日付に予約が存在するかどうかに関係なく、すべてのスケジュールを取得しながら、日付パラメーター(planningDate)に一致する予約のみを取得することです。
だから私は書いた:
SELECT s FROM Schedule as s LEFT JOIN s.reservations as r WHERE r.resDate = :planningDate order by s.startHour
LEFT JOINにもかかわらず、この日付の予約なしでスケジュールが取得されないのはなぜですか?
おそらく、ネイティブクエリと同様に、WHERE句と組み合わせると、LEFTJOINはINNERJOINのように見えます。
では、要件を満たすためにクエリをどのように変更できますか? JPQLに特定の機能が見つかりません。
ああ、これは確かにJPAの古典です。私が提供する次の答え-なぜそれが機能するのか正確に説明することはできませんが、私はあなたのためにこれを解決することができます
短い答え、試してみてください:
SELECT s FROM Schedule as s LEFT JOIN s.reservations as r WHERE
(r.resDate is null or r.resDate = :planningDate) order by s.startHour
(ここで重要なのは「r.resDateisnull」の部分です)
長い答え:これは休止状態/ JPAの人々によって機能しないと明示的に言われていますが、機能します。生成されたSQLも非常に効率的です。なぜこれが機能するのか誰かが説明できれば、私は最も感銘を受けます。私は何年も前にこのパターンを学びましたが、私の人生のどこにいるのか思い出せません。
注:これが機能しない場合が1つあります。これは、このスケジュールの予約がない場合です。この場合、私が提供できる唯一の答えは、クエリを「NoResultException」のtry/catchでラップし、where句なしで再度クエリを実行できることです(明らかに、予約がない場合は、resDateがオンの予約はありません) PlanningDate)
EclipseLink 2.5(Glassfish 4.0、Oracle 11g XEデータベース)の場合:
from Request r left join r.assignee
order by case when r.assignee.id is null then 0 else r.assignee.id end desc
生成されたクエリ部分(デカート乗算を使用):
FROM要求t0、ユーザーt1 WHERE((t1.ID = t0.assignee_id))ORDER BY CASE WHEN(t0.assignee_id IS NULL)THEN?ELSEt1。 ID END DESC)WHERE ROWNUM <=?)WHERE rnum>?
from Request r left join r.assignee as a
order by case when a.id is null then 0 else a.id end desc
生成されたクエリ部分(左結合を使用):
FROMはt1 LEFT OUTER JOINユーザーt0を要求します ON(t0.ID = t1.assignee_id)ORDER BY CASE WHEN(t0.ID IS NULL)THEN?ELSEt0。 ID END DESC)WHERE ROWNUM <=?)WHERE rnum>?
最後に、JPAのLEFTJOINの概念が適用できない場合があると思います。
最初の目標を思い出させる:
特定のplanningDateに一致する場合に、予約コレクションにのみデータを入力している間に発生したすべてのスケジュールを取得します(これらのそれぞれのスケジュールではそうです)。
実際、予約が私の基準に一致しないスケジュールを取得できたとしても、フェッチタイプが「熱心」であると宣言されている場合、それらのスケジュールは予約のコレクションをそれぞれ再読み込みするため、正確な「planningDate」への制限句。これは、他の制限なしにすべてのスケジュールのすべての予約を選択するのとまったく同じ動作です。
したがって、JPAでの私の問題に対する最も単純な適応ソリューションは、2つの要求を行うことです。最初にスケジュールを選択し、次にplanningDateに一致する予約を選択します。したがって、結果を1つのリストに再グループ化して、返すことができます。欠点は、予約コレクションが時間にロードされることです。
より良い解決策を見つけたら、私は感謝します。