在 grails 3 数据服务中查询与 JPA QL 的向后关联,对象上的 MissingMethodException executeQuery?
Querying backwards association with JPA QL in a grails 3 Data Service, MissingMethodException executeQuery on Object?
在收集作者及其书籍的数据库中,我们通过 Author
添加书籍作为 Book
个实例。
但是,Author
可能有尚未添加到数据库中的书籍。这就是为什么我们有一个外部理智计数器,告诉我们 Author
实际出版了多少本书。如果 numberOfKnownBooks
等于数据库中 Book
个实例的数量,那么我们认为我们有一个 Author
的完整参考书目。
一个SQL查询获取所有Authors
其参考书目是完整的将这样写在SQL:
select author.id, count(*)
from book inner join author on book.author_id=author.id
group by author.number_Of_Known_Books, author.id
having count(*) = author.number_Of_Known_Books
这里的难点在于连接指向相反的方向,正常的示例通常显示如何创建一个查询来获得 Books
与 Authors
的连接,而不是相反。
我在 Whosebug 中找到了一些文章,解释了如何在普通 JPQL 中做这样的事情(减去 group by ... 有复杂性)here,但是在 [=] 期望的 DSL 中这样做23=] 在 GORM 6.1+ 的数据服务中注释,我得到一个异常,发生在 AST 生成的代码的地牢中,说它无法在 java.lang.Object
上找到方法 executeQuery
。这是一个合理的抱怨,但我不知道为什么会这样。不幸的是,无法逐步调试此代码。
这是我的数据服务:
import grails.gorm.services.Query
import grails.gorm.services.Service
@Service
abstract class AuthorService {
@Query("""
select a.*, count(a.id)
from ${Book b} join ${b.author} a
group by a.numberOfKnownBooks, a.id
having count(*) = a.numberOfKnownBooks
""")
abstract List<Author> retrieveCompleteAuthors()
}
更新:根据 jeff 的说明删除了无用的注释@GrailsCompileStatic 和@Transactional
完整解决方案,使用正确的 JPQL 查询:
@Service(Author)
abstract class AuthorService {
@Query("""
select auth from ${Author auth} where auth.id in (
select a.id
from ${Book b} join ${b.author} a
group by a.numberOfKnownBooks, a.id
having count(*) = a.numberOfKnownBooks
)
""")
abstract List<Author> retrieveCompleteAuthors()
}
我预计这并不是您真正想要的 HQL,但这是一个单独的问题。如果您这样做,您询问的错误应该会消失...
import grails.gorm.services.Query
import grails.gorm.services.Service
@Service(Author)
abstract class AuthorService {
@Query('''
select a.*, count(a.id)
from ${Book b} join ${b.author} a
group by a.numberOfKnownBooks, a.id
having count(*) = a.numberOfKnownBooks
''')
abstract List<Author> retrieveCompleteAuthors()
}
在收集作者及其书籍的数据库中,我们通过 Author
添加书籍作为 Book
个实例。
但是,Author
可能有尚未添加到数据库中的书籍。这就是为什么我们有一个外部理智计数器,告诉我们 Author
实际出版了多少本书。如果 numberOfKnownBooks
等于数据库中 Book
个实例的数量,那么我们认为我们有一个 Author
的完整参考书目。
一个SQL查询获取所有Authors
其参考书目是完整的将这样写在SQL:
select author.id, count(*)
from book inner join author on book.author_id=author.id
group by author.number_Of_Known_Books, author.id
having count(*) = author.number_Of_Known_Books
这里的难点在于连接指向相反的方向,正常的示例通常显示如何创建一个查询来获得 Books
与 Authors
的连接,而不是相反。
我在 Whosebug 中找到了一些文章,解释了如何在普通 JPQL 中做这样的事情(减去 group by ... 有复杂性)here,但是在 [=] 期望的 DSL 中这样做23=] 在 GORM 6.1+ 的数据服务中注释,我得到一个异常,发生在 AST 生成的代码的地牢中,说它无法在 java.lang.Object
上找到方法 executeQuery
。这是一个合理的抱怨,但我不知道为什么会这样。不幸的是,无法逐步调试此代码。
这是我的数据服务:
import grails.gorm.services.Query
import grails.gorm.services.Service
@Service
abstract class AuthorService {
@Query("""
select a.*, count(a.id)
from ${Book b} join ${b.author} a
group by a.numberOfKnownBooks, a.id
having count(*) = a.numberOfKnownBooks
""")
abstract List<Author> retrieveCompleteAuthors()
}
更新:根据 jeff 的说明删除了无用的注释@GrailsCompileStatic 和@Transactional
完整解决方案,使用正确的 JPQL 查询:
@Service(Author)
abstract class AuthorService {
@Query("""
select auth from ${Author auth} where auth.id in (
select a.id
from ${Book b} join ${b.author} a
group by a.numberOfKnownBooks, a.id
having count(*) = a.numberOfKnownBooks
)
""")
abstract List<Author> retrieveCompleteAuthors()
}
我预计这并不是您真正想要的 HQL,但这是一个单独的问题。如果您这样做,您询问的错误应该会消失...
import grails.gorm.services.Query
import grails.gorm.services.Service
@Service(Author)
abstract class AuthorService {
@Query('''
select a.*, count(a.id)
from ${Book b} join ${b.author} a
group by a.numberOfKnownBooks, a.id
having count(*) = a.numberOfKnownBooks
''')
abstract List<Author> retrieveCompleteAuthors()
}