web-dev-qa-db-ja.com

JPQL Selectステートメントで新しいオブジェクトを作成する-避けるか、受け入れるか?

最近、次のようにJPQLステートメントで新しいオブジェクトを作成できることを学びました。

select new Family(mother, mate, offspr)
from DomesticCat as mother
    join mother.mate as mate
    left join mother.kittens as offspr

これは避けるべきなのか、むしろ受け入れるべきなのか?この機能の使用は、適切な慣行に照らしていつ正当化されますか?

60
mgamer

それを避けないでくださいで思い出されるように、完全に有効なユースケースがあるため、SELECT NEWがあります§ 10.2.7.2。 EJB 3.0 JPA仕様 :のSELECT節のJPQLコンストラクター式

SELECTリストでコンストラクターを使用して、1つ以上のJavaインスタンスを返します。指定されたクラスは、エンティティーである必要も、データベースにマップされる必要もありません。コンストラクター名は完全修飾である必要があります。

エンティティクラス名がSELECT NEW句で指定されている場合、結果のエンティティインスタンスは新しい状態になります。

SELECT NEW com.acme.example.CustomerDetails(c.id, c.status, o.count)
FROM Customer c JOIN c.orders o
WHERE o.count > 100

要するに、タイプセーフな方法でオブジェクトの完全なエンティティまたは完全なグラフを取得したくない場合は、SELECT NEWを使用します(Object[])。クエリの結果をエンティティクラスにマッピングするか、マッピングされていないクラスにマッピングするかは、選択によって異なります。典型的な例はリスト画面です(すべての詳細が必要なわけではありません)。

つまり、どこでも使用しないでください。使用を禁止しないでください(黒または白だけのものはほとんどありません)。

113
Pascal Thivent

データ転送オブジェクトを取得する場合、この種のクエリをよく使用します。たぶん、レポートはそれを使うのに良い場所かもしれません。単一のドメインオブジェクト(代わりにfrom from Familyなど)を取得するだけの場合、使用する理由はありません。

30
Arthur Ronald

Newで作成されたオブジェクトは、DTOである必要はありません。つまり、ビジネスレイヤーによってエクスポートされるオブジェクトです。 POJOドメインオブジェクト、つまり、ビジネスレイヤーによって内部的に使用されるオブジェクトにすることもできます。

この種のPOJOを完全なJPAエンティティの代わりに部分オブジェクトとして使用する理由は、特定の種類のJOINSでのパフォーマンスです。これを説明する優れたリソースは次のとおりです。 http://use-the-index-luke.com/sql/join/hash-join-partial-objects

7
gmournos