在做协会网站时,有一个API,是可以通过标签查询对应的文章。所以我在文章的 DAO , IArticleDAO 里有个函数
@Query("select a from ArticleTag a where a.tag in ?1 and a.article.status in ?2")
Page<Article> findArticleByTags(List<Tag> tags, String[] status, Pageable pageable);
但是到我上层 Services 查询回来的结果返回给 Controller 之后,发现返回的 Page<Article> 里面居然装的是 ArticleTag 对象。。。我懵了。查了好久发现原来是查询语句写错了,应该 select a.article
才对,于是改成
@Query("select a.article from ArticleTag a where a.tag in ?1 and a.article.status in ?2")
但是返回的还是 ArticleTag 。。。
于是我又猜了一下,可能是不能这么查询?试了一下改成以 ArticleTag.article 为查询对象
@Query("select a from ArticleTag.article a where ArticleTag.tag in ?1 and a.status in ?2")
于是出现了如下错误直接导致 Services 没法加载
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: ArticleTag.article is not mapped [select a from ArticleTag.article a where ArticleTag.tag in ?1 and a.status in ?2]
好吧。。。。上网再查一下 JPA 查询的文章,我发现了这篇 JPA JPQL 查询、排序.....(转)(那个“转”字我看得很不顺眼。。),里面的 关联(join) 部分 提到
在默认的查询中, Entity 中的集合属性默认不会被关联,集合属性默认是延迟加载 ( lazy-load ) 。
然后重新写了之后就变成现在这个了
@Query("select at.article from ArticleTag at join at.article where at.tag in ?1 and at.article.status in ?2 order by at.article.createDate")
继续使用 PageRequest 来指定通过文章的某个字段排序也是可以的。删掉 order by ,改在 PageRequest 里使用 article.createDate 即可。因为 JPA 查询实际上会把 PageRequest 里的排序拼接在 JQL 语句里面。实际发出去的 JPA 是跟上面在 Query 注解里的查询语句是一样的。
网友评论