Javaおよびjpaを使用して関数searchBookを実行しようとします。MediaとBookの2つのクラスがあります。BookはMediaを拡張します。そして、データを別のテーブルに保持します。以下のクエリからのデータ:
TypedQuery<Media> query = em.createQuery(
"SELECT m.title, b.isbn, b.authors"
+ " FROM Book b, Media m" + " WHERE b.isbn = :isbn"
+ " OR lower(m.title) LIKE :title"
+ " OR b.authors LIKE :authors", Media.class);
query.setParameter("isbn", book.getisbn());
query.setParameter("title", "%" + book.getTitle().toLowerCase()
+ "%");
query.setParameter("authors", "%" + book.getAuthors() + "%");
bookList = query.getResultList();
しかし、私はエラーを受け取りました:
Java.lang.IllegalArgumentException:複数の戻り値を持つクエリのTypedQueryを作成できません
JPAを使用するのはこれが初めてです。私は間違いを見つけることができません。
Media
とBook
をモデル化する方法の詳細については説明しませんが、この例外が発生する理由を少なくとも説明します。
あなたはやっている:
em.createQuery(someJPQL, Media.class);
つまり、someJPQL
を使用してクエリを作成すると、このクエリはMedia
エンティティのインスタンスを返します。
しかし、あなたのJPQL
は:
SELECT m.title, b.isbn, b.authors ...
したがって、クエリはタイプがMediaのエンティティを返しません。 2つの異なるエンティティから3つのフィールドを返します。 JPAエンジンがこれらの3つの列からMediaのインスタンスを魔法のように作成できる方法はありません。クエリが次のような場合、Mediaのインスタンスを返します。
select m from Media m ...
回避策として、他のエンティティ属性で構成されたエンティティを取得するには、クエリ内でエンティティを作成し、そのコンストラクタを提供します。
クエリ:
TypedQuery<Media> query = em.createQuery("SELECT NEW package_name.Media(m.title, b.isbn, b.authors)"
+ " FROM Book b, Media m"
+ " WHERE b.isbn = :isbn"
+ " OR lower(m.title) LIKE :title"
+ " OR b.authors LIKE :authors", Media.class);
エンティティ:
public Media(String title, int isbn, String author){
//-- Setting appropriate values
}
私はサンプルを提供し、それに応じてコンストラクターのデータ型を変更します。
それでもTypedQuery
を使用したい場合は、結果のタイプをObject[]
に変更できます。
List<Object[]> results = entityManager
.createQuery("SELECT m.title, b.isbn, b.authors ...", Object[].class)
.getResultList();
List
の各Object[]
は、データの行を表します。これには、その行で選択された値が、クエリで選択された順序で含まれています。要素0はタイトル、要素1はISBN、要素2は作成者です。意味のある方法で使用したい場合は、これらの値をキャストする必要があるでしょう。フィールド値は2つの異なるテーブルから取得されるので、それらをある種のコンテナーオブジェクトに格納できます。
List<MediaContainer> mediaList = new ArrayList<>();
for (Object[] row : results) {
MediaContainer container = new MediaContainer();
container.setTitle((String) row[0]);
container.setIsbn((int) row[1]);
container.setAuthors((String) row[2]);
mediaList.add(container);
}
私は...削除
Media.class
の
createQuery
より多くを返すためEntitiesこのソースで"SELECT m.title、b.isbn、b.authors"
例:
TypedQuery<Media> query = em.createQuery(
"SELECT m.title, b.isbn, b.authors"
+ " FROM Book b, Media m" + " WHERE b.isbn = :isbn"
+ " OR lower(m.title) LIKE :title"
+ " OR b.authors LIKE :authors");
代わりに@WebUser
List<EntityIDKey> companies =
getEntityManager().createQuery(sql, EntityIDKey.class).getResultList();
これを試して :
List<EntityIDKey> companies =
(List<EntityIDKey>)getEntityManager().createQuery(sql).getResultList();
私のために働く。
hibernateバージョン<4を使用している場合は、このバグに対応できます。
V3.5でも同じ問題が発生します。最後に、単純なクエリを使用して、各パラメーターを手動でキャストする必要がありました
ここの他のコメントを参照してください: https://groups.google.com/forum/#!topic/axonframework/eUd1d4rotMY