我尝试用java和jpa做函数searchBook。我有2个课程,分别是媒体和书。本书扩展了媒体。我将数据保存在不同的表中。我尝试从下面的查询中选择数据:
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。我找不到错误。
答案 0 :(得分:45)
作为一种变通方法,要获取由其他实体属性组成的实体,您可以在查询中创建它,为其提供构造函数。
查询:
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
}
我提供了示例,相应地更改了构造函数的数据类型。
答案 1 :(得分:31)
如果不详细了解Media
和Book
应该如何建模,我至少会解释为什么会出现此异常。
你在做:
em.createQuery(someJPQL, Media.class);
这意味着:使用someJPQL
创建查询,此查询将返回Media
实体的实例。
但是你的JPQL
是:
SELECT m.title, b.isbn, b.authors ...
因此查询不返回Media类型的实体。它返回来自两个不同实体的三个字段。您的JPA引擎无法从这3列神奇地创建Media实例。如果查询如下所示,查询将返回Media的实例:
select m from Media m ...
答案 2 :(得分:0)
如果你正在使用Hibernate版本&lt; 4,你可以遇到这个bug。
我和v3.5一样。最后我不得不使用简单的Query并手动转换每个参数
请在此处查看其他评论:https://groups.google.com/forum/#!topic/axonframework/eUd1d4rotMY
答案 3 :(得分:0)
@WebUser而不是
List<EntityIDKey> companies =
getEntityManager().createQuery(sql, EntityIDKey.class).getResultList();
试试这个:
List<EntityIDKey> companies =
(List<EntityIDKey>)getEntityManager().createQuery(sql).getResultList();
适合我。
答案 4 :(得分:0)
我......删除
的Media.class
createQuery
因为您在此来源中返回了更多实体 &#34; SELECT m.title,b.isbn,b.authors&#34;
例如:
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");
答案 5 :(得分:0)
如果您仍想使用TypedQuery
,可以将结果类型更改为Object[]
。
List<Object[]> results = entityManager
.createQuery("SELECT m.title, b.isbn, b.authors ...", Object[].class)
.getResultList();
每个Object[]
代表一行数据。它包含该行的选定值,按查询中选择的顺序排列。元素0是标题,元素1是ISBN,元素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);
}