点无效 属性 - MongoDB & Grails 3.3+
Point not a valid property - MongoDB & Grails 3.3+
在 Grails 中遇到一个非常奇怪的问题,MongoDB 在我的生产环境中出现以下错误。
java.lang.IllegalArgumentException: Property [location] is not a valid property of class [domain].Tracking
at org.grails.datastore.mapping.reflect.FieldEntityAccess$FieldEntityReflector.getPropertyReader(FieldEntityAccess.java:268)
at org.grails.datastore.mapping.reflect.FieldEntityAccess$FieldEntityReflector.getProperty(FieldEntityAccess.java:286)
at grails.gorm.validation.PersistentEntityValidator.validatePropertyWithConstraint(PersistentEntityValidator.groovy:319)
at grails.gorm.validation.PersistentEntityValidator.validate(PersistentEntityValidator.groovy:76)
at org.grails.datastore.gorm.GormValidationApi.doValidate(GormValidationApi.groovy:124)
at org.grails.datastore.gorm.GormValidationApi.validate(GormValidationApi.groovy:153)
at org.grails.datastore.gorm.GormValidateable$Trait$Helper.validate(GormValidateable.groovy:71)
at org.grails.datastore.gorm.GormValidateable$Trait$Helper$validate.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:136)
at [domain].Tracking.validate(Tracking.groovy)
at org.grails.datastore.gorm.GormInstanceApi.doSave(GormInstanceApi.groovy:332)
at org.grails.datastore.gorm.GormInstanceApi.doSave(GormInstanceApi.groovy)
at sun.reflect.GeneratedMethodAccessor113.invoke(Unknown Source)
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:98)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1225)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:947)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:930)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethodSafe(InvokerHelper.java:92)
at org.grails.datastore.gorm.GormInstanceApi$_save_closure5.doCall(GormInstanceApi.groovy:179)
at sun.reflect.GeneratedMethodAccessor112.invoke(Unknown Source)
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:98)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:264)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
at groovy.lang.Closure.call(Closure.java:418)
at org.codehaus.groovy.runtime.ConvertedClosure.invokeCustom(ConvertedClosure.java:54)
at org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:124)
at com.sun.proxy.$Proxy111.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:178)
at org.grails.datastore.gorm.GormEntity$Trait$Helper.save(GormEntity.groovy:151)
at org.grails.datastore.gorm.GormEntity$Trait$Helper$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:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:136)
at [domain].Tracking.save(Tracking.groovy)
at [domain].Tracking.save(Tracking.groovy)
at org.grails.datastore.gorm.GormEntity$save[=12=].call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:128)
at autovision.web.BootStrap$_closure1.doCall(BootStrap.groovy:139)
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:98)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:264)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1099)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
at groovy.lang.Closure.call(Closure.java:418)
at groovy.lang.Closure.call(Closure.java:412)
at grails.util.Environment.evaluateEnvironmentSpecificBlock(Environment.java:541)
at grails.util.Environment.executeForEnvironment(Environment.java:534)
at grails.util.Environment.executeForCurrentEnvironment(Environment.java:510)
at org.grails.web.servlet.boostrap.DefaultGrailsBootstrapClass.callInit(DefaultGrailsBootstrapClass.java:74)
at org.grails.web.servlet.context.GrailsConfigUtils.executeGrailsBootstraps(GrailsConfigUtils.java:65)
at org.grails.plugins.web.servlet.context.BootStrapClassRunner.onStartup(BootStrapClassRunner.groovy:53)
at grails.boot.config.GrailsApplicationPostProcessor.onApplicationEvent(GrailsApplicationPostProcessor.groovy:261)
at grails.boot.config.GrailsApplicationPostProcessor.onApplicationEvent(GrailsApplicationPostProcessor.groovy)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:393)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:347)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:883)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:144)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at grails.boot.GrailsApp.run(GrailsApp.groovy:84)
at grails.boot.GrailsApp.run(GrailsApp.groovy:393)
at grails.boot.GrailsApp.run(GrailsApp.groovy:380)
at grails.boot.GrailsApp$run.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:136)
at autovision.web.Application.main(Application.groovy:8)
当我尝试像这样将一个新的跟踪对象插入数据库时会发生这种情况:
Tracking tp = new Tracking()
tp.setUser(user)
nowCal.add(Calendar.MINUTE,i++)
tp.setCreated(nowCal.getTime())
tp.setSpeed(10f)
tp.setLocation(new Point(points[1],points[0]))
tp.save(flush:true)
user.addToTracking(tp);
我的跟踪 class 是这样定义的:
import grails.mongodb.geo.Point
class Tracking {
Point location
Date created
float speed
static belongsTo = [user:User]
static constraints = {
speed nullable:true
}
static mapping = {
location geoIndex:'2dsphere'
}
}
我真的看不出问题出在哪里,我想我已经正确定义了所有内容,正如 GORM 文档中显示的那样:http://gorm.grails.org/latest/mongodb/manual/#geoSpatial
另一件事是,当 运行 在非生产模式下时,这段代码工作得非常好。
所以执行 grails run-app
有效,但 grails prod run-app
无效..
如有任何帮助,我们将不胜感激。
谢谢
李.
我遇到了同样的问题,经过两天的调试终于找到了解决方法。
问题是由以下原因引起的:
- 有一个名为
org.grails.datastore.mapping.reflect.FieldEntityAccess
的 Grails 实用程序 class,显然用于使用反射访问实体字段。 class 有一个内部 class 叫做 FieldEntityReflector
。每次创建一个 FieldEntityAccess
实例时,都会在内部创建一个 FieldEntityReflector
实例。所有这些实例都存储在一个名为 REFLECTORS
的静态映射中,其键是实体名称,显然是出于性能原因。
- 在 bean 初始化期间,
mongoDatastore
bean 为每个实体创建一个 FieldEntityAccess
,传递一个 DocumentPersistentEntity
作为构造函数参数。
- 以同样的方式,
grailsDomainClassMappingContext
bean,不知道 mongoDatastore
为每个实体创建自己的 FieldEntityAccess
,将 KeyValuePersistentEntity
作为参数传递下去。那些 FieldEntityAccess
个实例及其对应的 EntityReflectors
不知道 mongo,因此不支持 mongo 特定类型,例如 Point
.
- 鉴于
REFLECTORS
映射键是实体名称,EntityReflectors
最后为同一实体创建,覆盖先前创建的反射器,并被所有 EntityReflector
个实例使用。
- 最后创建
grailsDomainClassMappingContext
个反射器时,当 mongo 尝试持久化实体并因此抛出错误时使用它们。
简而言之,在mongoDatastore
个bean之后初始化grailsDomainClassMappingContext
个bean时抛出错误。
在开发模式下,UrlMappingsGrailsPlugin
插件会创建一些 bean,用于允许 url 映射重新加载。这些 bean 在 mongoDatastore
bean 之前触发 grailsDomainClassMappingContext
bean 的实例化。由于 mongo bean 是稍后创建的,因此不会抛出错误。但是,在生产模式下,不会创建这些 beans,并且 mongoDatastore
在 grailsDomainClassMappingContext
之前创建,因此会抛出错误。
可能的解决方案
- 在
mongoDatastore
之前强制 grailsDomainClassMappingContext
bean 实例化: 经过几次尝试后我无法做到这一点,可能是因为 grails bean 实例化逻辑。
- 即使在生产模式下也强制
UrlMappingsGrailsPlugin
实例化:由于可能的性能影响,我不想那样做。
- 使用
FieldEntityAccess
class的静态方法clearReflectors
在系统初始化后清除所有反射器:**我决定这样做然后系统开始工作。我没有深入测试它,但能够正确地坚持 Point
。
为了调用该方法,我根据 grailsDomainClassMappingContext
和 mongoDatastore
创建了一个 bean 并调用了 FieldEntityAccess.clearReflectors()
package app.utils
import org.grails.datastore.mapping.mongo.MongoDatastore
import org.grails.datastore.mapping.reflect.FieldEntityAccess
import org.grails.datastore.mapping.model.MappingContext
class MongoDatastoreHolder {
MongoDatastore mongo
MappingContext context
MongoDatastoreHolder(MappingContext context, MongoDatastore mongo) {
this.context = context
this.mongo = mongo
FieldEntityAccess.clearReflectors()
}
}
并在 resources.groovy
中定义了那个 bean:
import app.utils.MongoDatastoreHolder
beans = {
mongoDatastoreHolder(MongoDatastoreHolder, ref('grailsDomainClassMappingContext'), ref('mongoDatastore')) { bean ->
bean.lazyInit = false
}
}
希望对您有所帮助,抱歉我的英语不好,这是我在 Whosebug 上的第一个回答。
在 Grails 中遇到一个非常奇怪的问题,MongoDB 在我的生产环境中出现以下错误。
java.lang.IllegalArgumentException: Property [location] is not a valid property of class [domain].Tracking
at org.grails.datastore.mapping.reflect.FieldEntityAccess$FieldEntityReflector.getPropertyReader(FieldEntityAccess.java:268)
at org.grails.datastore.mapping.reflect.FieldEntityAccess$FieldEntityReflector.getProperty(FieldEntityAccess.java:286)
at grails.gorm.validation.PersistentEntityValidator.validatePropertyWithConstraint(PersistentEntityValidator.groovy:319)
at grails.gorm.validation.PersistentEntityValidator.validate(PersistentEntityValidator.groovy:76)
at org.grails.datastore.gorm.GormValidationApi.doValidate(GormValidationApi.groovy:124)
at org.grails.datastore.gorm.GormValidationApi.validate(GormValidationApi.groovy:153)
at org.grails.datastore.gorm.GormValidateable$Trait$Helper.validate(GormValidateable.groovy:71)
at org.grails.datastore.gorm.GormValidateable$Trait$Helper$validate.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:136)
at [domain].Tracking.validate(Tracking.groovy)
at org.grails.datastore.gorm.GormInstanceApi.doSave(GormInstanceApi.groovy:332)
at org.grails.datastore.gorm.GormInstanceApi.doSave(GormInstanceApi.groovy)
at sun.reflect.GeneratedMethodAccessor113.invoke(Unknown Source)
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:98)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1225)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:947)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:930)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethodSafe(InvokerHelper.java:92)
at org.grails.datastore.gorm.GormInstanceApi$_save_closure5.doCall(GormInstanceApi.groovy:179)
at sun.reflect.GeneratedMethodAccessor112.invoke(Unknown Source)
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:98)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:264)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
at groovy.lang.Closure.call(Closure.java:418)
at org.codehaus.groovy.runtime.ConvertedClosure.invokeCustom(ConvertedClosure.java:54)
at org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:124)
at com.sun.proxy.$Proxy111.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:178)
at org.grails.datastore.gorm.GormEntity$Trait$Helper.save(GormEntity.groovy:151)
at org.grails.datastore.gorm.GormEntity$Trait$Helper$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:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:136)
at [domain].Tracking.save(Tracking.groovy)
at [domain].Tracking.save(Tracking.groovy)
at org.grails.datastore.gorm.GormEntity$save[=12=].call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:128)
at autovision.web.BootStrap$_closure1.doCall(BootStrap.groovy:139)
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:98)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:264)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1099)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
at groovy.lang.Closure.call(Closure.java:418)
at groovy.lang.Closure.call(Closure.java:412)
at grails.util.Environment.evaluateEnvironmentSpecificBlock(Environment.java:541)
at grails.util.Environment.executeForEnvironment(Environment.java:534)
at grails.util.Environment.executeForCurrentEnvironment(Environment.java:510)
at org.grails.web.servlet.boostrap.DefaultGrailsBootstrapClass.callInit(DefaultGrailsBootstrapClass.java:74)
at org.grails.web.servlet.context.GrailsConfigUtils.executeGrailsBootstraps(GrailsConfigUtils.java:65)
at org.grails.plugins.web.servlet.context.BootStrapClassRunner.onStartup(BootStrapClassRunner.groovy:53)
at grails.boot.config.GrailsApplicationPostProcessor.onApplicationEvent(GrailsApplicationPostProcessor.groovy:261)
at grails.boot.config.GrailsApplicationPostProcessor.onApplicationEvent(GrailsApplicationPostProcessor.groovy)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:393)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:347)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:883)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:144)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at grails.boot.GrailsApp.run(GrailsApp.groovy:84)
at grails.boot.GrailsApp.run(GrailsApp.groovy:393)
at grails.boot.GrailsApp.run(GrailsApp.groovy:380)
at grails.boot.GrailsApp$run.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:136)
at autovision.web.Application.main(Application.groovy:8)
当我尝试像这样将一个新的跟踪对象插入数据库时会发生这种情况:
Tracking tp = new Tracking()
tp.setUser(user)
nowCal.add(Calendar.MINUTE,i++)
tp.setCreated(nowCal.getTime())
tp.setSpeed(10f)
tp.setLocation(new Point(points[1],points[0]))
tp.save(flush:true)
user.addToTracking(tp);
我的跟踪 class 是这样定义的:
import grails.mongodb.geo.Point
class Tracking {
Point location
Date created
float speed
static belongsTo = [user:User]
static constraints = {
speed nullable:true
}
static mapping = {
location geoIndex:'2dsphere'
}
}
我真的看不出问题出在哪里,我想我已经正确定义了所有内容,正如 GORM 文档中显示的那样:http://gorm.grails.org/latest/mongodb/manual/#geoSpatial
另一件事是,当 运行 在非生产模式下时,这段代码工作得非常好。
所以执行 grails run-app
有效,但 grails prod run-app
无效..
如有任何帮助,我们将不胜感激。
谢谢
李.
我遇到了同样的问题,经过两天的调试终于找到了解决方法。
问题是由以下原因引起的:
- 有一个名为
org.grails.datastore.mapping.reflect.FieldEntityAccess
的 Grails 实用程序 class,显然用于使用反射访问实体字段。 class 有一个内部 class 叫做FieldEntityReflector
。每次创建一个FieldEntityAccess
实例时,都会在内部创建一个FieldEntityReflector
实例。所有这些实例都存储在一个名为REFLECTORS
的静态映射中,其键是实体名称,显然是出于性能原因。 - 在 bean 初始化期间,
mongoDatastore
bean 为每个实体创建一个FieldEntityAccess
,传递一个DocumentPersistentEntity
作为构造函数参数。 - 以同样的方式,
grailsDomainClassMappingContext
bean,不知道mongoDatastore
为每个实体创建自己的FieldEntityAccess
,将KeyValuePersistentEntity
作为参数传递下去。那些FieldEntityAccess
个实例及其对应的EntityReflectors
不知道 mongo,因此不支持 mongo 特定类型,例如Point
. - 鉴于
REFLECTORS
映射键是实体名称,EntityReflectors
最后为同一实体创建,覆盖先前创建的反射器,并被所有EntityReflector
个实例使用。 - 最后创建
grailsDomainClassMappingContext
个反射器时,当 mongo 尝试持久化实体并因此抛出错误时使用它们。
简而言之,在mongoDatastore
个bean之后初始化grailsDomainClassMappingContext
个bean时抛出错误。
在开发模式下,UrlMappingsGrailsPlugin
插件会创建一些 bean,用于允许 url 映射重新加载。这些 bean 在 mongoDatastore
bean 之前触发 grailsDomainClassMappingContext
bean 的实例化。由于 mongo bean 是稍后创建的,因此不会抛出错误。但是,在生产模式下,不会创建这些 beans,并且 mongoDatastore
在 grailsDomainClassMappingContext
之前创建,因此会抛出错误。
可能的解决方案
- 在
mongoDatastore
之前强制grailsDomainClassMappingContext
bean 实例化: 经过几次尝试后我无法做到这一点,可能是因为 grails bean 实例化逻辑。 - 即使在生产模式下也强制
UrlMappingsGrailsPlugin
实例化:由于可能的性能影响,我不想那样做。 - 使用
FieldEntityAccess
class的静态方法clearReflectors
在系统初始化后清除所有反射器:**我决定这样做然后系统开始工作。我没有深入测试它,但能够正确地坚持Point
。
为了调用该方法,我根据 grailsDomainClassMappingContext
和 mongoDatastore
创建了一个 bean 并调用了 FieldEntityAccess.clearReflectors()
package app.utils
import org.grails.datastore.mapping.mongo.MongoDatastore
import org.grails.datastore.mapping.reflect.FieldEntityAccess
import org.grails.datastore.mapping.model.MappingContext
class MongoDatastoreHolder {
MongoDatastore mongo
MappingContext context
MongoDatastoreHolder(MappingContext context, MongoDatastore mongo) {
this.context = context
this.mongo = mongo
FieldEntityAccess.clearReflectors()
}
}
并在 resources.groovy
中定义了那个 bean:
import app.utils.MongoDatastoreHolder
beans = {
mongoDatastoreHolder(MongoDatastoreHolder, ref('grailsDomainClassMappingContext'), ref('mongoDatastore')) { bean ->
bean.lazyInit = false
}
}
希望对您有所帮助,抱歉我的英语不好,这是我在 Whosebug 上的第一个回答。