Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to update embedded class field #125

Open
3 of 4 tasks
Tirla-Alin opened this issue May 7, 2020 · 2 comments
Open
3 of 4 tasks

Unable to update embedded class field #125

Tirla-Alin opened this issue May 7, 2020 · 2 comments

Comments

@Tirla-Alin
Copy link

Task List

  • Steps to reproduce provided
  • Stacktrace (if present) provided
  • Example that reproduces the problem uploaded to Github
  • Full description of the issue provided (see below)

Steps to Reproduce

  1. Create a simple grails 4.0.1, gorm 7.0.2.RELEASE (with mongo plugin support) application
  2. Create one class in the groovy/src folder
//import grails.gorm.dirty.checking.DirtyCheck

//@DirtyCheck
class EmbeddedClass {
    String aField
}
  1. Create a domain class in grails-app
class DomainClass implements Serializable {

    EmbeddedClass embeddedClass

    static embedded = ['embeddedClass']

    static constraints = {
    }
}
  1. Insert an entity
DomainClass.withNewTransaction {
    def domain = new DomainClass()
    domain.embeddedClass = new EmbeddedClass()
    domain.embeddedClass.aField = "ogValue"
    domain.save(flush: true, failOnError: true)
}
  1. Try to update domain.embeddedClass.aField
    @Secured(['IS_AUTHENTICATED_ANONYMOUSLY'])
    def updateEmbedded() {
        def domainClass = DomainClass.findById(1)
        domainClass.embeddedClass = new EmbeddedClass()
        domainClass.embeddedClass.aField = "anothervalue"
        domainClass.save(flush:true, failOnError: true)

        return respond("response": "response")
    }
  1. Check the value in the db.

Expected Behaviour

Ability to update embedded class field.

Actual Behaviour

Unable to update embedded class field. Tried with new entity (provided example), update only the field, tried to add (DirtyCheck annotation) as I saw in some other issue -> that will throw an exception. Relevant stacktrace is as follows:

java.lang.IllegalStateException: Either class [org.avora.lib.models.EmbeddedClass] is not a domain class or GORM has not been initialized correctly or has already been shutdown. Ensure GORM is loaded and configured correctly before calling any methods on a GORM entity.
	at org.grails.datastore.gorm.GormEnhancer.stateException(GormEnhancer.groovy:467)
	at org.grails.datastore.gorm.GormEnhancer.findStaticApi(GormEnhancer.groovy:298)
	at org.grails.datastore.gorm.GormEnhancer.findStaticApi(GormEnhancer.groovy:294)
	at org.grails.datastore.mapping.mongo.engine.codecs.PersistentEntityCodec.encodeUpdate(PersistentEntityCodec.groovy:285)
	at org.grails.datastore.mapping.mongo.engine.codecs.PersistentEntityCodec.encodeUpdate(PersistentEntityCodec.groovy:203)
	at org.grails.datastore.mapping.mongo.engine.codecs.PersistentEntityCodec.encodeEmbeddedUpdate(PersistentEntityCodec.groovy:443)
	at org.grails.datastore.mapping.mongo.engine.codecs.PersistentEntityCodec.encodeUpdate(PersistentEntityCodec.groovy:251)
	at org.grails.datastore.mapping.mongo.engine.codecs.PersistentEntityCodec.encodeUpdate(PersistentEntityCodec.groovy)
	at org.grails.datastore.mapping.mongo.MongoCodecSession.flush(MongoCodecSession.groovy:158)
	at org.grails.datastore.mapping.mongo.AbstractMongoSession.flush(AbstractMongoSession.java:74)
	at org.grails.datastore.gorm.GormInstanceApi.doSave(GormInstanceApi.groovy:368)
	at org.grails.datastore.gorm.GormInstanceApi.doSave(GormInstanceApi.groovy)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:101)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1217)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1041)
	at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:1011)
	at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:994)
	at org.codehaus.groovy.runtime.InvokerHelper.invokeMethodSafe(InvokerHelper.java:97)
	at org.grails.datastore.gorm.GormInstanceApi$_save_closure5.doCall(GormInstanceApi.groovy:180)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:101)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:263)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1041)
	at groovy.lang.Closure.call(Closure.java:405)
	at org.codehaus.groovy.runtime.ConvertedClosure.invokeCustom(ConvertedClosure.java:50)
	at org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:122)
	at com.sun.proxy.$Proxy112.doInSession(Unknown Source)
	at org.grails.datastore.mapping.core.DatastoreUtils.execute(DatastoreUtils.java:319)
	at org.grails.datastore.gorm.AbstractDatastoreApi.execute(AbstractDatastoreApi.groovy:40)
	at org.grails.datastore.gorm.GormInstanceApi.save(GormInstanceApi.groovy:179)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.save(GormEntity.groovy:153)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper$save$4.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:135)
	at org.mypackage.DomainClass.save(DomainClass.groovy)
	at org.mypackage.DomainClass.save(DomainClass.groovy)
	at org.grails.datastore.gorm.GormEntity$save.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:127)

Environment Information

  • Operating System: macOS Catalina 10.15.4
  • GORM Version: 7.0.2.RELEASE
  • Grails Version (if using Grails): 4.0.1
  • JDK Version: 1.8.0_231

Example Application

  • TODO: link to github repository with example that reproduces the issue
@Tirla-Alin
Copy link
Author

Update:
Setting
grails.mongodb.engine=mapping
in application.properties seems to fix the issue. As far as I understood from documentation this will affect performance, so I am still looking for the correct solution to this.

@puneetbehl puneetbehl transferred this issue from grails/grails-data-mapping May 8, 2020
@puneetbehl
Copy link
Contributor

I think the root problem is that it is assuming EmbeddedClass as PersistentEntity whereas it is NOT. So, if you either annotate the Embedded class with @grails.gorm.annotation.Entity or move it to the grails-app/domains folder.

@puneetbehl puneetbehl self-assigned this May 8, 2020
@puneetbehl puneetbehl added this to the 7.0.1 milestone May 8, 2020
@puneetbehl puneetbehl modified the milestones: 7.0.1, 7.0.2 Jul 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants