33

我尝试使用 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。我找不到错误。

4

6 回答 6

64

作为一种解决方法,要获取由其他实体属性组成的实体,您可以在查询中创建它,并为其提供构造函数。

询问 :

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
}

我提供了示例,相应地更改构造函数的数据类型。

于 2012-05-30T08:14:47.583 回答
48

在不详细说明如何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 ...
于 2012-05-30T07:21:41.033 回答
7

如果您仍想使用TypedQuery,您可以将结果类型更改为Object[].

List<Object[]> results = entityManager
    .createQuery("SELECT m.title, b.isbn, b.authors ...", Object[].class)
    .getResultList();

Object[]中的每个List代表一行数据。它包含该行的选定值,这些值按照它们在查询中的选择顺序排列。元素 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);
}
于 2018-02-10T08:48:46.010 回答
1

@WebUser 而不是做

List<EntityIDKey> companies = 
getEntityManager().createQuery(sql, EntityIDKey.class).getResultList();

试试这个 :

List<EntityIDKey> companies =
(List<EntityIDKey>)getEntityManager().createQuery(sql).getResultList();

为我工作。

于 2017-03-18T16:23:12.710 回答
0

如果您使用的是 < 4 的 Hibernate 版本,则可以遇到此错误。

我对 v3.5 也有同样的问题。最后我不得不使用简单的查询并手动转换每个参数

在此处查看其他评论:https ://groups.google.com/forum/#!topic/axonframework/eUd1d4rotMY

于 2014-01-28T16:29:25.107 回答
0

我...删除

媒体类

创建查询

因为您在此来源“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");
于 2017-08-01T14:18:54.213 回答