Details
-
Type:
Bug
-
Status:
Closed
-
Priority:
Critical
-
Resolution: Fixed
-
Affects Version/s: 1.1.1
-
Component/s: Persistence
-
Labels:None
-
Environment:OSX JDK 1.6
Description
quite simply,
class Party {
String type
static constraints =
{ tablePerHierarchy false }}
class Person extends Party {
NameInfo name
static embedded = ['name']
}
class Organization extends Party {
String name
String taxId
}
class NameInfo {
String firstName
String lastName
}
instantiating an Organization and saving it causes no problems. Instantiating a Person and trying to save it causes the following exception to occur:
org.codehaus.groovy.runtime.InvokerInvocationException: groovy.lang.MissingPropertyException: No such property: save for class: Person
at org.jsecurity.web.servlet.JSecurityFilter.doFilterInternal(JSecurityFilter.java:382)
at org.jsecurity.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:180)
Caused by: groovy.lang.MissingPropertyException: No such property: save for class: Person
at TestController$_closure10.doCall(TestController.groovy:215)
at TestController$_closure10.doCall(TestController.groovy)
... 2 more
Why? Was working previously off a 1.1.1 snapshot. But upgrade to 1.1.1 killed the code.
Thanks,
Chris
-
Hide
- FaceAndNose-bug-report-22052009.zip
- 22/May/09 9:38 AM
- 16 kB
- Arnold Franz
-
- grails-app/conf/BootStrap.groovy 0.1 kB
- grails-app/conf/Config.groovy 3 kB
- grails-app/conf/DataSource.groovy 0.6 kB
- grails-app/conf/UrlMappings.groovy 0.2 kB
- grails-app/conf/spring/resources.groovy 0.0 kB
- grails-app/.../NoseExpenderController.groovy 0.3 kB
- grails-app/domain/Face.groovy 0.1 kB
- grails-app/domain/Nose.groovy 0.1 kB
- grails-app/i18n/messages.properties 3 kB
- grails-app/i18n/messages_de.properties 3 kB
- grails-app/i18n/messages_es.properties 3 kB
- grails-app/i18n/messages_fr.properties 2 kB
- grails-app/i18n/messages_it.properties 2 kB
- grails-app/i18n/messages_ja.properties 2 kB
- grails-app/i18n/messages_nl.properties 3 kB
- grails-app/.../messages_pt_BR.properties 3 kB
- grails-app/i18n/messages_ru.properties 4 kB
- grails-app/i18n/messages_th.properties 5 kB
- grails-app/.../messages_zh_CN.properties 2 kB
- grails-app/views/error.gsp 2 kB
- grails-app/views/index.gsp 0.4 kB
- grails-app/views/layouts/main.gsp 0.7 kB
- grails-app/views/.../changeNose.gsp 0.2 kB
- grails-app/views/noseExpender/index.gsp 0.4 kB
- test/unit/FaceTests.groovy 0.2 kB
- test/.../NoseExpenderControllerTests.groovy 0.2 kB
- test/unit/NoseTests.groovy 0.2 kB
Activity
- All
- Comments
- Work Log
- History
- Activity
- Git Commits
I am getting the same problem. It also includes the delete method. I've got it narrowed down to 2 test cases that have to run one after the other in order to reproduce the problem. I will work on an example, too.
I did this demo application which shows the problem:
class Face {
Integer width
Integer heigth
Nose nose
}
class Nose {
Integer length
static belongsTo = [face:Face]
}
I want to update an existing Nose instance. First, I load the face which owns the nose:
def face = Face.get(faceId)
I get the corresponding nose to update its length :
def nose = face.nose
nose.length = 10
Now, I want to save the nose:
nose.save(flush:true).
In Grails 1.1 : OK, no problem, nose is saved.
In Grails 1.1.1 : KO: I get this error : groovy.lang.MissingPropertyException: No such property: save for class: Nose.
Doing a face.save() works correctly (cascading to nose which is correctly saved (both in Grails 1.1 and 1.1.1)
I seems that Nose is not recognized as a Domain class.
I have this issue too. Only seems to happen when the Child record (Nose in the above example) is retrieved off its owner. It is still possible to create and then save the Child without error, and also retrieve the child directly (i.e. Nose.get(1)) and save it ok, as long as its parent association is not involved.
As per Burt Beckwith's post, he managed to find a workaround which I haven't tested yet, but I'd like to post it here so that people would know about it.
----snipped from threaded post http://www.nabble.com/save()-method-on-domain-class-seen-as-property-td23659161.html#a23663421 -----
I played with this a bit and it seems like a Groovy bug to me - there doesn't seem to be a sensible Grails-specific reason why it thinks save() is a property invocation and not a method invocation.
I found a workaround though. HibernateGrailsPlugin (using HibernatePluginSupport) wires up the GORM methods and most are lazily initialized to reduce startup time. The save() call is failing to invoke the MissingMethodException that triggers this lazy initialization but I found that if I call DomainClass.count() or list() that it does wire up the methods and save() works after that.
So a hackish fix (until this is fixed in an upcoming release) would be to put count() calls in BootStrap for the problematic domain classes, or even for all of them, e.g.
class BootStrap {
def grailsApplication
def init = { servletContext ->
for (dc in grailsApplication) {
dc.clazz.count()
}
}
}
For what it's worth, I first hit this problem when I switched from dbCreate = "create-drop" to dbCreate = "update"... switch back and the problem goes away.
Now I have to have some code similar to what Chris Chen commented above.
I think the severity of this should be bumped to blocker. On about all my classes calling save() does not work anymore since 1.1.1. I can reproduce this all the time, if you need a sample to debug just shout.
We have the same problem here. Thanks for the hints.
Domainclass.count() in BootStrap.groovy works for us too.
I also get this problem. However it is only on domain objects from a plugin. Also it is also only on Tomcat 6.0. When I deploy the app for the first time I get the problem. If I then stop and restart the server it goes away. Not good !!
In case it is useful to anyone, here is a variation of Chris Chen's workaround that I got to work:
import org.codehaus.groovy.grails.commons.ApplicationHolder class BootStrap { def init = { servletContext -> // workaround for GRAILS-4580 ApplicationHolder.application.domainClasses.each { dc -> dc.clazz.count() } } }
The work around throws a new type of exception.
I have the same problem as described above, but within the bootstrap. I' m trying to fill up the database with a little default data and when i switched from dbCreate: "create-drop" to "update" the trouble started.
So what I do create a few parents and try to save them and the exception appears. If I read well everyone here got the exception on child instances.
After applying the described workarounds I now get the following error:
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: Parent
I can't tell exactly when I started getting this exception, I was working through the examples in Definitive guide to grails 2nd edition and up to Chapter 16 (adding JMS) I started getting the exception.
I tried a bunch of measures (restart app, clean, call domainclass.count() in bootstrap) and the only measure that worked was to switch back the database from "update" to "create-drop" and use Dillon's workaround in Bootstrap.groovy.
This issue is a little scary, let's hope the patch due in 1.1.2 definitively fixes it.
Please attach an example that reproduces the problem.