views:

21

answers:

2

I have 2 domains :

class JobProcess {

    static constraints = {
       scriptUser(blank:false)
       scriptType()
       scriptName()
       scriptPath()
       scriptArgs(size:0..1000,nullable:true)
       scriptDateCreated(nullable:true)
       scriptDateStarted(nullable:true)
       scriptDateFinished(nullable:true)
       scriptRun()
       scriptId()
    }

    static mapping = {
      version false
    }
    User scriptUser  
    String scriptType
    String scriptName
    String scriptPath
    String scriptArgs
    Date scriptDateCreated
    Date scriptDateStarted
    Date scriptDateFinished
    String scriptRun
    int scriptId
}

and :

class User {

  static hasMany = [ jobs : JobProcess ]

    static constraints = {
        login(unique: true, blank: false)
        password(password: true, blank: false)
        email(blank: false, emailAddr: true, maxSize: 50)
        firstName(blank:false, maxSize:32)
        lastName(blank:false, maxSize:32)
        phoneNo(nullable: true)
    }

    static mapping = {
        sort lastName: 'asc'
    }

    String login
    String firstName
    String lastName
    String phoneNo
    String email
    String password

    boolean locked = false

    String toString()
    {
        if (firstName == "")
            return email
        return fullName()
    }

    String fullName()
    {
        return firstName + " " + lastName
    }
}

And this query :

selected = JobProcess.withCriteria{
      like("scriptUser", "%${params.name}%")
      maxResults(params.max as int)
      firstResult(params.offset? params.offset.toInteger():0)
      }

I get errors :

ERROR property.BasicPropertyAccessor  - IllegalArgumentException in class: common.User, getter method of property: id      
ERROR errors.GrailsExceptionResolver  - java.lang.ClassCastException@503ca729

I also try by replacing like part by :
eq("scriptUser", 1) but I get same errors.

What's wrong ? Any ideas ?

+2  A: 

If params.name is the User's firstName, try this:

JobProcess.withCriteria {
    scriptUser {
        like('firstName', "%${params.name}%")
    }
    maxResults(params.max as int)
    firstResult(params.offset ? params.offset.toInteger() : 0)
}

If params.name is something different, can you clarify your question to explain how you're using it?

Here's proof of concept code:

// grails-app/domain/JobProcess.groovy
class JobProcess {
    User scriptUser
}

// grails-app/domain/User.groovy
class User {
    String name
}

// grails-app/conf/Bootstrap.groovy
def init = { servletContext ->
    def foo = new User(name: 'foo').save()
    def bar = new User(name: 'bar').save()
    new JobProcess(scriptUser: foo).save()
    new JobProcess(scriptUser: bar).save()
    new JobProcess(scriptUser: bar).save()

    def result = JobProcess.withCriteria {
        scriptUser {
            like('name', 'ba%')
        }
    }
    result.each {
        println "Result ID: ${it.id}"
    }

    // prints:
    // Result ID: 2
    // Result ID: 3
 }

This is based on the "Querying Associations" section here.

Rob Hruska
Thanks, now I understand my mistake. I have to querying by my User domain. So by firstName and not scriptUser.
Fabien Barbier
A: 

I can also combine by firstName and lastName :

selected = JobProcess.withCriteria {
          scriptUser {
            or {
              like('firstName', "%${params.name}%")
              like('lastName', "%${params.name}%")
            }
          }
          maxResults(params.max as int)
          firstResult(params.offset ? params.offset.toInteger() : 0)
      }

Is there a way to use directly fullName() ?

Fabien Barbier
To answer your question, I don't believe there is. `withCriteria` is just an abstraction for Hibernate's `Criteria`, which I'm not sure support querying on transient fields. It'd probably be easier just to make `fullName` a property of the domain.
Rob Hruska