简体   繁体   English

Grails:使用Where查询选择具有给定ID(子查询)的Child of Parent的子代

[英]Grails: selecting Children of Parent of Child with given id (subquery) with a Where Query

Using grails 2.1.0 and default H2 database. 使用grails 2.1.0和默认的H2数据库。 I've got the following domains: 我有以下域:

class Project {
    static hasMany = [tasks: Task]
}

class Task {
    Date dateCreated
    static belongsTo = [project: Project]
}

I've got a task id and want to get all tasks from the task's (of the given id) project, using the all-new gorm where queries . 我有一个任务ID,并希望使用全新的where where查询从任务(给定ID)的项目中获取所有任务。 Here's my attempt: 这是我的尝试:

def tasks = Task.where {
    project == property('project').of { id == firstTask.id }
}.list()

(firstTask.id is the given task id, the code is snipped from a test) (firstTask.id是给定的任务ID,从测试中删除了代码)

And the unpleasant unexpected result is: 令人不愉快的意外结果是:

IllegalArgumentException occurred calling getter of so.q.grom.subqueries.Project.id
org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of so.q.grom.subqueries.Project.id
    at grails.gorm.DetachedCriteria.list_closure2(DetachedCriteria.groovy:639)
    at grails.gorm.DetachedCriteria.withPopulatedQuery_closure9(DetachedCriteria.groovy:890)
    at org.grails.datastore.gorm.GormStaticApi.withDatastoreSession_closure18(GormStaticApi.groovy:555)
    at org.grails.datastore.mapping.core.DatastoreUtils.execute(DatastoreUtils.java:301)
    at org.grails.datastore.gorm.AbstractDatastoreApi.execute(AbstractDatastoreApi.groovy:34)
    at org.grails.datastore.gorm.GormStaticApi.withDatastoreSession(GormStaticApi.groovy:554)
    at grails.gorm.DetachedCriteria.withPopulatedQuery(DetachedCriteria.groovy:873)
    at grails.gorm.DetachedCriteria.list(DetachedCriteria.groovy:638)
    at grails.gorm.DetachedCriteria.list(DetachedCriteria.groovy:637)
    at GormSubqueriesSpec.should get tasks from the same project(GormSubqueriesSpec.groovy:32)
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
    ... 10 more

Why!? 为什么!? :( How's that different from: :(有什么区别于:

def tasks = Task.findAll() {
    dateCreated < property('dateCreated').of { id == secondTask.id }
}

To clarify, using HQL, what I want would be: 为了澄清,使用HQL,我想要的是:

def tasks = Task.findAll(
        'from Task task where task.project = (select t.project from Task t where t.id = :taskId)',
        [taskId: firstTask.id]
)

But I want it in "where queries". 但我希望在“ where查询”中使用它。

For Your convenience (and me being precise), a Grails project with the domains and tests for the queries is available here 为了您的方便(我很精确), 此处提供了包含域和查询测试的Grails项目

You should raise this as an issue. 您应该提出这个问题。 The following example compiles and runs: 以下示例编译并运行:

def tasks = Task.where {
    project == property('project')
}.list()

but adding a sub-query causes problems. 但是添加子查询会导致问题。 At the very least, the error message should be more informative. 至少,错误消息应该提供更多信息。 But I don't see why it couldn't work in theory. 但是我不明白为什么它在理论上是行不通的。

Anyway, in the meantime HQL is probably your best bet. 无论如何,与此同时,HQL可能是您最好的选择。

There is maybe an easier way of doing it via dynamic finders: 通过动态查找器可能有一种更简单的方法:

Task.findAllByProject( thisTask.project )

I don't know the details about your project, but you can add this method into the domain class Task: 我不知道有关您的项目的详细信息,但是您可以将此方法添加到域类Task中:

public Collection<Task> findAllTasksinPoject() {
    return Task.findAllByProject( project )
}

and you can call it on every instance of a Task class. 您可以在Task类的每个实例上调用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM