3

私の元の問題はhttps://stackoverflow.com/questions/12172614/hql-join-without-foreign-key-reference でしたが、これに対する解決策が見つからなかったため、JPA を使用したネイティブ クエリに進みました。entityManager の createNativeQuery は Query オブジェクトを返し、それが を返しますList<Object[]>。本質的にエラーが発生しやすいため、リストの反復中にインデックスを処理したくありません。したがって、他のソリューションを調べたところ、JPQLのコンストラクター式が解決策の1つとして見つかりました。

テーブル構造は

Schema1 -TableA

 - NameColumn
 - PhoneColumn

対応するJavaクラスは

    public class PersonSearch implements Serializable {

    public PersonSearch (String NameColumn, String PhoneColumn) {
        this.name = NameColumn;
        this.phone = PhoneColumn;
    }

    private String name;

    private String phone;

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public String getPhone() {
    return phone;
    }

    public void setPhone(String phone) {
    this.phone = phone;
    }
    }

クエリは

 Select NEW com.xyz.PersonSearch(ms.NameColumn, ms.PhoneColumn) From Schema1.TableA ms Where ms.PhoneColumn='9134409930'

entityManager API を使用してこのクエリを実行している間

entityManager.createQuery(queryString, PersonSearch.class);

エラーを下回っています。

Caused by: org.hibernate.hql.ast.QuerySyntaxException: Schema1.TableA is not mapped   [Select NEW com.xyz.PersonSearch(ms.NameColumn, ms.PhoneColumn) From Schema1.TableA ms Where ms.PHONE='9134409930']

コードの何が問題になっていますか? 何か案が ?

4

1 に答える 1

8

「ProEJB3JavaPersistenceAPI」という本によると

コンストラクター式

複数の式を含むより強力な形式のSELECT句は、コンストラクター式です。これは、ユーザー指定のオブジェクト型を使用してクエリの結果を格納することを指定します。次のクエリについて考えてみます。

SELECT NEW example.EmployeeDetails(e.name, e.salary, e.department.name)
FROM Employee e

このクエリの結果のタイプはタイプexample.EmployeeDetailsです。EmployeeDetailsクエリプロセッサはクエリの結果を反復処理するときに、クエリにリストされている式の種類に一致するコンストラクタを使用する新しいインスタンスをインスタンス化します。この場合、式のタイプはString、Double、およびStringであるため、クエリエンジンは、これらのクラスタイプのコンストラクターで引数を検索します。したがって、結果のクエリコレクションの各行は EmployeeDetails、従業員名、給与、および部門名を含むインスタンスになります。

結果のオブジェクトタイプは、オブジェクトの完全修飾名を使用して参照する必要があります。ただし、クラスをデータベースにマップする必要はありません。句にリストされている式と互換性のあるコンストラクターを持つクラスは、コンストラクSELECTター式で使用できます。

コンストラクター式は、他のアプリケーション層で使用するために、粗粒度のデータ転送オブジェクトまたはビューオブジェクトを構築するための強力なツールです。これらのオブジェクトを手動で作成する代わりに、単一のクエリを使用して、Webページに表示できるビューオブジェクトをまとめることができます。

サンプルコードは次のとおりです

List result = em.createQuery("SELECT NEW example.EmpMenu(e.name, e.department.name) " +
         "FROM Project p JOIN p.employees e " +
         "WHERE p.name = ?1 " +
        "ORDER BY e.name").setParameter(1, projectName).getResultList();

EmpMenuクラスは単純なpojoであり、アノテーションはありませんが、コンストラクター式に一致する正しいコンストラクターがあります。結果は、返された各行のEmpMenuオブジェクトのリストです。

SQLの「....FromSchema1.TableA ms ..」の部分は、マップされているエンティティを参照する必要があると思います。したがって、エンティティをTableAにマップする必要があります。次に、jpqlは、「.... From MyTableAEntity ms ...」の行に沿ったものになります。ここで、MyTableAEntityには、DBテーブルTableAにマップするすべての適切なjpaアノテーションがあります。ブックスニペットに記載されているように、「SELECT NEW ...」のターゲットはマッピングする必要はありませんが、FROM句で参照されるエンティティはマッピングします。

于 2012-09-05T16:55:49.620 に答える