您能帮我找出以下JPQL查询的错误吗?它应按其类型过滤书籍。
查询还有其他OR条件,由于更好的可读性,我已将其删除(有或没有其他条件,错误相同)。
@Query("SELECT b FROM Book b WHERE " +
"b in (select distinct b1 FROM Book b1 inner join b1.genres genre where genre in :genres)")
List<Book> searchBooks(@Param("genres") List<Genre> genres);
以下是stacktrace:
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: , near line 1, column 197 [select count(b) FROM *.domain.Book AS b WHERE b.id = (select distinct b1.id FROM *.domain.Book b1 inner join b1.genres genre where genre in :genres_0_, :genres_1_)]
Book和Genre类之间的关系是ManyToMany的非定向。
@ManyToMany
@JoinTable(name = "books_genres",
joinColumns = @JoinColumn(name = "BOOK_ID"),
inverseJoinColumns = @JoinColumn(name = "GENRE_ID"))
private List<Genre> genres;
我已经分别检查了子查询,它可以工作:
@Query("select distinct b1 FROM Book b1 inner join b1.genres genre where genre in :genres")
List<Book> searchBooksByGenre(@Param("genres") List<Genre> genres);
是否有可能以这种方式使用子查询?
答案 0 :(得分:2)
使用嵌套选择的查询是正常的,但如果要搜索实体集合,则必须使用MEMBER关键字而不是IN
。
以下是对MEMBER
和IN
:https://stackoverflow.com/a/9820394/784594的一个很好的解释。另请看这里:http://www.objectdb.com/java/jpa/query/jpql/collection#NOT_MEMBER_OF_
但是,即使文档说根据作为参数传递的列表进行比较时使用IN
关键字,如果您传递实体列表而不是hibernate,则表现出奇怪的行为原始值列表。我最近遇到了这个,使用MEMBER
解决了问题。我不确定这是否是一个hibernate错误,或者所有其他提供程序是否都以相同的方式运行。
在ObjectDB的文档中,您可能会读到它以同样的方式处理IN
和MEMBER
。在我看来,如果JPA提供者应该有足够的信息来解释查询,即使在两种情况下都使用了IN
,也没有理由应该有2个关键字。
答案 1 :(得分:0)
不幸的是,我遇到了与数据格式有关的memberOf的其他问题,当传递一个类型列表并检查它们是否存在于书籍类型列表中时,查询将因数据格式异常而失败。
@Query("SELECT b FROM Book b WHERE " +
":genres MEMBER OF b.genres")
@Param("genres") List<Genre> genres
会导致以下内容(1和4是传递给查询的genres参数中的Genre对象的ID):
Caused by: org.h2.jdbc.JdbcSQLException: Data conversion error converting "(1, 4)"; SQL statement:
我已经放弃了上述解决方案,并设法使用&#34;子查询&#34;作为普通查询,然后继续向查询添加条件。
所以最终解决方案如下:
@Query("select distinct b1 FROM Book b1 inner join b1.genres genre where genre in :genres AND (---additional querys---)")