Question

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

Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top