Error: Cannot create TypedQuery for query with more than one return
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I try to do the function searchBook with java and jpa. I have 2 classes which are Media and Book. Book extends Media. And I keep the data in the different table. I try to select the data from the query below:
TypedQuery 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();
But I got the error:
java.lang.IllegalArgumentException: Cannot create TypedQuery for query with more than one return
This is the first time I use JPA. I can't find the the mistake.
回答1:
Without goind into details about how Media and Book should be modeled, I will at least explain why you get this exception.
You're doing:
em.createQuery(someJPQL, Media.class);
This means: create a query using someJPQL, and this query will return instances of the Media entity.
But your JPQL is:
SELECT m.title, b.isbn, b.authors ...
So the query does not return entities of type Media. It returns three fields, from two different entities. There is no way your JPA engine could magically create instances of Media from these 3 columns. A query would return instances of Media if it looked like this:
select m from Media m ...
回答2:
As a workaround, to get entity composed by other entity attributes, you can create it within query, providing constructor for it.
Query :
TypedQuery 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);
Entity :
public Media(String title, int isbn, String author){ //-- Setting appropriate values }
I have provided sample, change the datatypes of the constructor accordingly.
回答3:
if your are using Hibernate version
I go same problem with v3.5. Finally i had to use simple Query and cast each parameter manually
List companies = getEntityManager().createQuery(sql, EntityIDKey.class).getResultList();
Try this :
List companies = (List)getEntityManager().createQuery(sql).getResultList();
works for me.
回答5:
I... remove
Media.class
of
createQuery
because you return more Entities in this source "SELECT m.title, b.isbn, b.authors"
Ex.:
TypedQuery 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");
回答6:
If you still want to use TypedQuery you can change the result type to Object[]. You'll have to cast the results though.