2

私はJPA2.0を初めて使用しますが、理解できないことがいくつかあります。

私はいくつかのテーブルを持っています:



    CUST table (for customers)
    --------------------------
    CUST_ID   (pk, integer)
    CUST_NAME (varchar)



    ORD table (for orders)
    ----------------------
    ORD_ID     (pk, integer)
    ORD_STATUS (char) can be: 'N' for new, 'S' for shipped, 'D' for delivered
    CUST_ID    (fk, integer)

関係は単純な「1対多」です(すべての顧客が多くの注文を行うことができます)。

表の内容:



    CUST_ID | CUST_NAME
    -------------------
     1      | elcaro
     2      | tfosorcim
     3      | elppa



    ORD_ID | ORD_STATUS | CUST_ID
    -----------------------------
     2     | N          | 1
     3     | N          | 1
     4     | N          | 1
     5     | S          | 1
     6     | S          | 1
     7     | D          | 1
     8     | D          | 1
     9     | D          | 1
     10    | D          | 2
     11    | N          | 2
     12    | S          | 3
     13    | S          | 3

クラスに注釈を付ける方法は次のとおりです。



    @Entity(name = "Customer")
    @Table(name = "CUST")
    public class Customer implements Serializable
    {
        private static final long serialVersionUID = 1L;

        @Id
        @Column(name = "CUST_ID")
        private Integer id;

        @Column(name = "CUST_NAME")
        private String name;

        @OneToMany(mappedBy = "customer")
        private List<Order> orders;

        // Default constructor, getters and setters (no annotations on these)
    }



    @Entity(name = "Order")
    @Table(name = "ORD")
    public class Order implements Serializable
    {
        private static final long serialVersionUID = 1L;

        @Id
        @Column(name = "ORD_ID")
        private Integer id;

        @Column(name = "ORD_STATUS")
        private Character status;

        @ManyToOne
        @JoinColumns
        (
          {
            @JoinColumn(name = "CUST_ID", referencedColumnName = "CUST_ID")
          }
        )
        private Customer customer;

        // Default constructor, getters and setters (no annotations on these)
    }

すべてが正常に機能します。次のJPQLクエリは、期待した結果をもたらします。

`select c from Customer c`

タイプCustomerの3つのオブジェクトを返します。各オブジェクトには、その顧客に属する注文が含まれています。

しかし、ここで、ステータス「N」の注文を持つ顧客のリストと、関連する注文(もちろん、ステータス「N」の注文のみ)を抽出したいと思います。古き良き時代には、次のようなSQLクエリを作成していました。



    select      c.cust_id,
                c.cust_name,
                o.ord_id,
                o.ord_status
    from        cust c
    inner join  ord o on (o.cust_id = c.cust_id)
    where       o.ord_status = 'N'

そしてそれは次の結果セットを返したでしょう:



    CUST_ID | CUST_NAME | ORD_ID | ORD_STATUS
    -----------------------------------------
     1      | elcaro    | 2      | N
     1      | elcaro    | 3      | N
     1      | elcaro    | 4      | N
     2      | tfosorcim | 11     | N

ただし、次のJPQLクエリでは、期待どおりの結果が得られません。

`select distinct c from Customer c join c.orders o where o.status = 'N'`

正しい顧客のセットを返します(顧客「elppa」にはステータス「N」の注文がなく、正しく除外されます)が、各顧客には、ステータスに関係なく、注文の完全なセットが含まれます。'where'句は、抽出する必要のある顧客のセットを決定するためにのみ評価され、その後、永続性プロバイダーが関係をナビゲートして、注文の完全なセットを抽出し始めるようです。それについて少し考えて、私はそれが理にかなっていることを認めなければなりません。

次に、別のJPQLクエリを試しました。

`select c, o from Customer c join c.orders o where o.status = 'N'`

このJPQLクエリは、前のSQLクエリによって生成された結果と同様の結果を生成します。各結果(予想どおり4つの結果)は2オブジェクト配列であり、最初のオブジェクトはタイプCustomerで、2番目のオブジェクトはタイプOrderです。ただし、ここでも、タイプCustomerのオブジェクトには、関連する注文の完全なセットが含まれています(今回は予想どおり)。注文はCustomerオブジェクトに含まれていませんが、SQL結果セットの場合と同様に、個別に返されることは言うまでもありません。

ここでの質問は次のとおりです。ステータス「N」の注文がない顧客だけでなく、ステータスが「」ではない関連注文(リレーションシップナビゲーション中に取得)を除外するJPQLクエリを作成することは可能ですか。 N'も?私が取得できるようにしたいのは、各顧客にステータス「N」の注文のみが含まれる2顧客の結果です。

Java EE 6チュートリアルを読み、例の1つ(Order Application)に私のようなスキーマがありますが、(ダウンロードしたソースコードに)このようなクエリが見つかりませんでした。

上記は標準的な動作だと思いますが、(Eclipseアダプタを介して)Oracle Weblogic 12cサーバーを使用しており、永続性プロバイダーはEclipseLinkのようです。

前もって感謝します。

よろしくお願いします、

ステファノ

4

1 に答える 1

4

JPAはオブジェクトを処理し、オブジェクトにはIDがあり、どのように照会されても同じです。where句が何であっても、返されるCustomerオブジェクトは同じCustomerオブジェクトであり、同じ関係を持つ必要があります。これは、キャッシング、オブジェクトID、および一貫性にとって重要です。

2番目のクエリは、おそらくあなたが望むことを行うための正しい方法です。JOIN FETCH(EclipseLink 2.4以降)でエイリアスを使用して実行しようとしていることを実行することは可能ですが、お勧めしません。

http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL#JOIN_FETCHを参照して ください。

于 2012-04-18T13:54:48.097 に答える