Using grails 2.1.0 and default H2 database. 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. 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)

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:

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".

For Your convenience (and me being precise), a Grails project with the domains and tests for the queries is available here

有帮助吗?

解决方案

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.

其他提示

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:

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

and you can call it on every instance of a Task class.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top