Quantcast

Call to Service causes "not-null property references a null or transient value"

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Call to Service causes "not-null property references a null or transient value"

ChrisGen
I'm receiving a "not-null property references a null or transient value" error on an object that failed validation.  The error occurs whenever I call a Service.  The Service method just contains a "println".  Can someone explain to me why this happens?  Why does the error go away if I comment out the Service call?

I'm pretty new to Grails, and this is my first post in this forum.  Glad to take any suggestions anyone has.

Here's my setup:

========= ./controllers/hello/VacationController.groovy ===============
class VacationController {

    def buyVacationHomeService

    def index = {
        // Initial data setup
        def child = new Child()
        def parent = new Parent(pets:5)
        parent.addToChildren(child).save()

        // Recreate issue
        def currParent = Parent.get(1)
        currParent.pets = 50 // Make sure we fail validation
        currParent.removeFromChildren(Child.get(1))

        if (currParent.validate()) {
            println "Valid"
        } else {
            println "Invalid"  // This will always happen
        }

        buyVacationHomeService.callRealtor() // Error occurs here
    }
}

========= ./domain/hello/Parent.groovy ===============
class Parent {

    Integer pets
    static hasMany = [ children:Child ]

    static constraints = {
       pets(range:0..5)
    }

    static mapping = {
        children cascade: "all-delete-orphan"
    }
}

========= ./domain/hello/Child.groovy ===============
class Child {
    static belongsTo = [ myParent: Parent ]
}

========= ./services/hello/BuyVacationHomeService.groovy ===============
class BuyVacationHomeService {
    def callRealtor() {
        println "callRealtor()"
    }
}

========= ./views/vacation/index.gsp ===============
<html><head><title>Title</title></head><body>Body</body></html>

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Call to Service causes "not-null property references a null or transient value"

Jonathan Rosenberg
The ""not-null property reference ..." exception occurs when Hibernate
tries to save to the DB and finds a "dependent object" missing.     I
would expect it to be caused by the save(), though the error won't
appear until the session is flushed (as farf as I know).

Are you saying that if you remove the line

         buyVacationHomeService.callRealtor() // Error occurs here

you don't get the exception?

Try changing the save() to save(flush:true) & see what happens.

--
Jonathan Rosenberg
Founder & Executive Director
Tabby's Place, a Cat Sanctuary
http://www.tabbysplace.org/


On Tue, Mar 27, 2012 at 1:22 PM, ChrisGen <[hidden email]> wrote:

> I'm receiving a "not-null property references a null or transient value"
> error on an object that failed validation.  The error occurs whenever I call
> a Service.  The Service method just contains a "println".  Can someone
> explain to me why this happens?  Why does the error go away if I comment out
> the Service call?
>
> I'm pretty new to Grails, and this is my first post in this forum.  Glad to
> take any suggestions anyone has.
>
> Here's my setup:
>
> ========= ./controllers/hello/VacationController.groovy ===============
> class VacationController {
>
>    def buyVacationHomeService
>
>    def index = {
>        // Initial data setup
>        def child = new Child()
>        def parent = new Parent(pets:5)
>        parent.addToChildren(child).save()
>
>        // Recreate issue
>        def currParent = Parent.get(1)
>        currParent.pets = 50 // Make sure we fail validation
>        currParent.removeFromChildren(Child.get(1))
>
>        if (currParent.validate()) {
>            println "Valid"
>        } else {
>            println "Invalid"  // This will always happen
>        }
>
>        buyVacationHomeService.callRealtor() // Error occurs here
>    }
> }
>
> ========= ./domain/hello/Parent.groovy ===============
> class Parent {
>
>    Integer pets
>    static hasMany = [ children:Child ]
>
>    static constraints = {
>       pets(range:0..5)
>    }
>
>    static mapping = {
>        children cascade: "all-delete-orphan"
>    }
> }
>
> ========= ./domain/hello/Child.groovy ===============
> class Child {
>    static belongsTo = [ myParent: Parent ]
> }
>
> ========= ./services/hello/BuyVacationHomeService.groovy ===============
> class BuyVacationHomeService {
>    def callRealtor() {
>        println "callRealtor()"
>    }
> }
>
> ========= ./views/vacation/index.gsp ===============
> <html><head><title>Title</title></head><body>Body</body></html>
>
>
>
> --
> View this message in context: http://grails.1312388.n4.nabble.com/Call-to-Service-causes-not-null-property-references-a-null-or-transient-value-tp4509578p4509578.html
> Sent from the Grails - user mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Call to Service causes "not-null property references a null or transient value"

ChrisGen
Jonathan - thanks for your reply:
Yes - I remove the "buyVacationHomeServices.callRealtor()" line, and it works fine.

I tried adding "flush:true" to "parent.addToChildren(child).save(flush:true)", but the exception still occurs.  

I can't see how removing the service call should have any impact on the controller operation.  Very weird.

Here's a more detailed list of the exception I'm getting:
==================
Error 500: Executing action [test] of controller [hello.VacationController] caused exception: not-null property references a null or transient value: hello.Child.myParent; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value: hello.Child.myParent
Servlet: grails
URI: /hello/grails/vacation/test.dispatch
Exception Message: not-null property references a null or transient value: hello.Child.myParent
Caused by: not-null property references a null or transient value: hello.Child.myParent
Class: VacationController
==================
org.hibernate.PropertyValueException: not-null property references a null or transient value: hello.Child.myParent
        at hello.BuyVacationHomeService$$EnhancerByCGLIB$$d1ae787b.callRealtor(<generated>)
        at hello.BuyVacationHomeService$callRealtor.call(Unknown Source)
        at hello.VacationController$_closure1.doCall(VacationController.groovy:22)
        at hello.VacationController$_closure1.doCall(VacationController.groovy)
        at java.lang.Thread.run(Thread.java:662)
==================

-Chris
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Call to Service causes "not-null property references a null or transient value"

Jonathan Rosenberg
Adding flush:true won't make the problem go away, it will just make it
occur earlier if that save is the problem.

BTW: hardwiring id's in your get calls is a bad idea.

Here is a thought.  Remove this statement

                   currParent.removeFromChildren(Child.get(1))

and see what happens.  Leave the service call in.

--
Jonathan Rosenberg
Founder & Executive Director
Tabby's Place, a Cat Sanctuary
http://www.tabbysplace.org/


On Tue, Mar 27, 2012 at 4:26 PM, ChrisGen <[hidden email]> wrote:

> Jonathan - thanks for your reply:
> Yes - I remove the "buyVacationHomeServices.callRealtor()" line, and it
> works fine.
>
> I tried adding "flush:true" to
> "parent.addToChildren(child).save(flush:true)", but the exception still
> occurs.
>
> I can't see how removing the service call should have any impact on the
> controller operation.  Very weird.
>
> Here's a more detailed list of the exception I'm getting:
> ==================
> Error 500: Executing action [test] of controller [hello.VacationController]
> caused exception: not-null property references a null or transient value:
> hello.Child.myParent; nested exception is
> org.hibernate.PropertyValueException: not-null property references a null or
> transient value: hello.Child.myParent
> Servlet: grails
> URI: /hello/grails/vacation/test.dispatch
> Exception Message: not-null property references a null or transient value:
> hello.Child.myParent
> Caused by: not-null property references a null or transient value:
> hello.Child.myParent
> Class: VacationController
> ==================
> org.hibernate.PropertyValueException: not-null property references a null or
> transient value: hello.Child.myParent
>        at
> hello.BuyVacationHomeService$$EnhancerByCGLIB$$d1ae787b.callRealtor(<generated>)
>        at hello.BuyVacationHomeService$callRealtor.call(Unknown Source)
>        at hello.VacationController$_closure1.doCall(VacationController.groovy:22)
>        at hello.VacationController$_closure1.doCall(VacationController.groovy)
>        at java.lang.Thread.run(Thread.java:662)
> ==================
>
> -Chris
>
> --
> View this message in context: http://grails.1312388.n4.nabble.com/Call-to-Service-causes-not-null-property-references-a-null-or-transient-value-tp4509578p4510111.html
> Sent from the Grails - user mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Call to Service causes "not-null property references a null or transient value"

ChrisGen
My understanding is that if a Domain instance fails validate(), then any changes to that instance won't be persisted to the database.  This seems to work great, UNLESS I make a call to a service within my controller action.  Calling a service after the following steps seems to cause unexpected behavior within grails/hibernate:
1 Remove object from Parent of one-to-many bidirectional relationship.
2. Setup data so that Validate() on Parent side returns false
3. Call Service.  Child removed in step 1 will cause exception because parent doesn't exist.

John -
I checked to be sure, but the flush:true doesn't change the location of the error - it still occurs within the service call.  Getting rid of the removeFrom* method call definitely gets around the error, so I think it's fair to assume that this is essential to recreating the issue.  It seems that the "removeFromChildren" severs the Parent / Child link.  However, since the Child BelongsTo a Parent, and I'm not deleting the Child, the Child object is left invalid.  
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Call to Service causes "not-null property references a null or transient value"

Jonathan Rosenberg

I'm curious.  Does it matter if you add

   static transactional = false

To the service?

On Mar 28, 2012 9:37 AM, "ChrisGen" <[hidden email]> wrote:
My understanding is that if a Domain instance fails validate(), then any
changes to that instance won't be persisted to the database.  This seems to
work great, UNLESS I make a call to a service within my controller action.
Calling a service after the following steps seems to cause unexpected
behavior within grails/hibernate:
1 Remove object from Parent of one-to-many bidirectional relationship.
2. Setup data so that Validate() on Parent side returns false
3. Call Service.  Child removed in step 1 will cause exception because
parent doesn't exist.

John -
I checked to be sure, but the flush:true doesn't change the location of the
error - it still occurs within the service call.  Getting rid of the
removeFrom* method call definitely gets around the error, so I think it's
fair to assume that this is essential to recreating the issue.  It seems
that the "removeFromChildren" severs the Parent / Child link.  However,
since the Child BelongsTo a Parent, and I'm not deleting the Child, the
Child object is left invalid.


--
View this message in context: http://grails.1312388.n4.nabble.com/Call-to-Service-causes-not-null-property-references-a-null-or-transient-value-tp4509578p4512295.html
Sent from the Grails - user mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Call to Service causes "not-null property references a null or transient value"

sethfuller
In reply to this post by ChrisGen
You could try modifying your code like this:

      // Recreate issue
        def currParent = Parent.get(1)
        currParent.pets = 50 // Make sure we fail validation
        currParent.validate()
        if (!currParent.hasErrors()) {
           currParent.removeFromChildren(Child.get(1))
        }

The removeFromChild can't succeed if the parent won't save due to validation errors, so this would workaround that.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Call to Service causes "not-null property references a null or transient value"

ChrisGen
Jonathan/Seth - thanks for your suggestions.  Both worked to get around the problem.

I wonder if calling a transactional service causes the current (controller action) session to be closed?  If so, perhaps grails/hibernate closes the session differently when calling a service than when it automatically closes at the end of the controller action.

It almost seems like there's a bug in how grails is handling the situation.  If it's going to complain about a parentless Child, then it should do it even when I'm not calling a service.  What I'm seeing seems inconsistent.

-Chris


On 3/28/2012 11:21 AM, sethfuller [via Grails] wrote:
You could try modifying your code like this:

      // Recreate issue
        def currParent = Parent.get(1)
        currParent.pets = 50 // Make sure we fail validation
        currParent.validate()
        if (!currParent.hasErrors()) {
           currParent.removeFromChildren(Child.get(1))
        }

The removeFromChild can't succeed if the parent won't save due to validation errors, so this would workaround that.


To unsubscribe from Call to Service causes "not-null property references a null or transient value", click here.
NAML
Loading...