0

Say, for a system, I had Student and User objects, like so:

User { 
}

Student {
    User user //not nullable
    static belongsTo = [User]
}
Teacher {
    static belongsTo = [user:User]
}

I have a lot of code written against these models, and plenty of dynamic finders in it

def u1 = new User().save( flush: true)
new Student( user: u1 ).save( flush: true)
...

def s = Student.findByUser( springSecurityService.currentUser)
//s can be null
def t = Teacher.findByUser( springSecurityService.currentUser)
//t can be null
if( s != null)
    //do something with 's'
if( t != null)
    //do something with 't'
...

And this all worked fine. But I wanted to update my domain model to add cascading access from User to Student. So I did:

User {
  Student student //nullable
}

And I would save a user like this:

new User( student: new Student() ).save( flush: true)

But the problem is, when I try to access 's' like I did above.

If the Student.findByUser can find one such student, then it works.
But if it should return null, it gives an error instead.

def s = Student.findByUser( springSecurityService.currentUser)   

will result in:

org.h2.jdbc.JdbcSQLException                                                    

Parameter #2 is not set; SQL statement:

select this_.id as id18_0_, this_.version as version18_0_, from student this_ where this_.id=? limit ? [90012-173]

I know I can access the student object through the user object like user.student, but I would like to be able to keep the existing code as it is.

I've seen this thread, and it had a similar problem, but no resolution grails email list


Is this a bug? What can I do to get around it? Am I not setting up my domain models properly?

Thanks

  • Class `User` seems wrong. Remove the `user` property and define `static belongsTo = [user: User]` like you did for the `Teacher` class – saw303 Aug 01 '14 at 07:24
  • @saw303 Yeah, but that didn't change a thing. –  Aug 01 '14 at 07:47
  • Since it is a bidirectional one-to-one mapping why don't you do it in three steps. First create and save the user. Then create the student, assign the user to it and save the student. Then update the user and assign the student to it. – saw303 Aug 01 '14 at 08:27
  • @saw303 the error appears when I try to find a provider that doesn't exist though. So I create a user, set its student to null. Then I try to find student-by-user for that user, which should give me an empty result. It results in an error though –  Aug 01 '14 at 08:30

1 Answers1

0

As an alternative, you could try something like this using hasOne instead of belongsTo.

class User {
    static hasOne = [student:Student, teacher:Teacher]
    static constraints = {
        student unique:true, nullable: true
        teacher unique:true, nullable: true
    }
}

class Student {
    User user
}

class Teacher {
    User user
}

It still cascades and appears to handle null searches fine.

Derek
  • 132
  • 1
  • 5