|
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> |
|
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 |
|
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 |
|
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 |
|
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. |
|
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 |
|
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. |
|
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: |
| Powered by Nabble | Edit this page |
