简体   繁体   中英

Is 'applicationContext' forbidden as a domain property name in Grails 2.4.3?

After migrating from Grails 2.2.4 to 2.4.3, a domain class with a property named applicationContext throws exceptions when using that property in criteria queries.

class WebResource {
     String applicationContext
}

class ResourceService {
  public WebResource getResourceByContext(String ctx) {
     WebResource.withCriteria() {
         eq('applicationContext', ctx)
     }
  }
}

A call to getResourceByContext() throws an exception:

org.hibernate.QueryException: could not resolve property: applicationContext of: org.mydomain.WebResource
 at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:83)
        at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:77)
        at org.hibernate.persister.entity.AbstractEntityPersister.getSubclassPropertyTableNumber(AbstractEntityPersister.java:1995)
        at org.hibernate.persister.entity.BasicEntityPropertyMapping.toColumns(BasicEntityPropertyMapping.java:61)
        at org.hibernate.persister.entity.AbstractEntityPersister.toColumns(AbstractEntityPersister.java:1970)
        at org.hibernate.loader.criteria.CriteriaQueryTranslator.getColumns(CriteriaQueryTranslator.java:518)
        at org.hibernate.loader.criteria.CriteriaQueryTranslator.findColumns(CriteriaQueryTranslator.java:534)
        at org.hibernate.criterion.SimpleExpression.toSqlString(SimpleExpression.java:82)
        at org.hibernate.loader.criteria.CriteriaQueryTranslator.getWhereCondition(CriteriaQueryTranslator.java:417)
        at org.hibernate.loader.criteria.CriteriaJoinWalker.(CriteriaJoinWalker.java:123)
        at org.hibernate.loader.criteria.CriteriaJoinWalker.(CriteriaJoinWalker.java:92)
        at org.hibernate.loader.criteria.CriteriaLoader.(CriteriaLoader.java:97)
        at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1663)
        at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:380)
        at org.codehaus.groovy.grails.orm.hibernate.query.AbstractHibernateCriteriaBuilder.invokeMethod(AbstractHibernateCriteriaBuilder.java:1639)
        at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:907)
        at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:884)
        at org.grails.datastore.gorm.GormStaticApi$_withCriteria_closure11.doCall(GormStaticApi.groovy:304)
        at sun.reflect.GeneratedMethodAccessor254.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1207)
        at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1110)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1016)
        at groovy.lang.Closure.call(Closure.java:423)
        at org.codehaus.groovy.runtime.ConvertedClosure.invokeCustom(ConvertedClosure.java:51)
        at org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:81)
        at com.sun.proxy.$Proxy29.doInSession(Unknown Source)
        at org.grails.datastore.mapping.core.DatastoreUtils.execute(DatastoreUtils.java:302)
        at org.grails.datastore.gorm.AbstractDatastoreApi.execute(AbstractDatastoreApi.groovy:37)
        at org.grails.datastore.gorm.GormStaticApi.withCriteria(GormStaticApi.groovy:303)
        at org.mydomain.WebResource.withCriteria(WebResource.groovy)

Is having domain properties with the name 'applicationContext' not allowed in Grails 2.4.3? I could not find a reference to this scenario being forbidden in the Grails release notes, upgrade guides, or JIRA. I have worked around this issue by renaming the field and changing GORM references to the new name:

class WebResource {
    String appContext
    appContext column: 'APPLICATION_CONTEXT'
    public String getApplicationContext() {
        return appContext
    }

    public void setApplicationContext(String c) {
        appContext = c
    }
}

Given the name clash with the Spring ApplicationContext I suspect you've found the best answer already - name the property something else and use a mapping definition to set the database column name. I would recommend you don't add the getter/setter pair but just use the property name appContext directly in your code, as there are more than likely places in Grails core or plugins that assume (quite reasonably in my opinion) that a property named applicationContext is the Spring object rather than anything else.

Don't fight the conventions unless you have to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM