Grails 3.2.4 отказывается сохранять экземпляр домена: java.lang.IllegalArgumentException: объект не является экземпляром объявляющего класса

Я обновляюсь с Grails 2.4.4 до Grails 3.2.4.

Я настроил несколько фабрик, чтобы помочь мне с тестированием, фабрика ролей работает нормально, которая запускается до создания пользователей. Тогда у меня есть следующий код:

        println "create user."
        def testUser = new User(username: '[email protected]', firstName: "admin", lastName: "admin", email: "[email protected]")
        println "User. :: " + testUser
        println "User class. :: " + testUser.getClass().toString()
        println("User Errors: " + testUser.errors)
        testUser.save()
        println "create user2."
        def testUser2 = new User(username: '[email protected]', email: '[email protected]', firstName: "trade", lastName: "trade").save()

Из которых выход:

create user
User. :: Person: [email protected]
User class. :: class UserManage.User
User Errors: grails.validation.ValidationErrors: 0 errors

2017-01-10 10:21:18.400 ERROR --- [           main] o.s.boot.SpringApplication               : Application startup failed

java.lang.IllegalArgumentException: object is not an instance of declaring class
        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.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1426)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
        at groovy.lang.MetaBeanProperty.getProperty(MetaBeanProperty.java:62)
        at groovy.lang.MetaClassImpl.invokePropertyOrMissing(MetaClassImpl.java:1245)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1217)
        at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1125)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:812)
        at org.grails.validation.ConstrainedPropertyBuilder.doInvokeMethod(ConstrainedPropertyBuilder.java:74)
        at groovy.util.BuilderSupport.invokeMethod(BuilderSupport.java:67)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeOnDelegationObjects(ClosureMetaClass.java:446)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:369)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024)
        at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:69)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:166)
        at UserManage.User$__clinit__closure2.doCall(User.groovy:79)
        at UserManage.User$__clinit__closure2.doCall(User.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.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1426)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024)
        at groovy.lang.Closure.call(Closure.java:414)
        at UserManage.User$__clinit__closure2.call(User.groovy)
        at groovy.lang.Closure.call(Closure.java:408)
        at UserManage.User$__clinit__closure2.call(User.groovy)
        at org.grails.validation.DefaultConstraintEvaluator.evaluateConstraintsMap(DefaultConstraintEvaluator.java:240)
        at org.grails.validation.DefaultConstraintEvaluator.evaluateConstraints(DefaultConstraintEvaluator.java:132)
        at org.grails.validation.DefaultConstraintEvaluator.evaluateConstraints(DefaultConstraintEvaluator.java:119)
        at org.grails.validation.DefaultConstraintEvaluator.evaluate(DefaultConstraintEvaluator.java:108)
        at org.grails.core.DefaultGrailsDomainClass.initializeConstraints(DefaultGrailsDomainClass.java:755)
        at org.grails.core.DefaultGrailsDomainClass.getConstrainedProperties(DefaultGrailsDomainClass.java:746)
        at org.grails.validation.GrailsDomainClassValidator.validate(GrailsDomainClassValidator.java:76)
        at org.grails.orm.hibernate.AbstractHibernateGormInstanceApi.save(AbstractHibernateGormInstanceApi.groovy:122)
        at org.grails.datastore.gorm.GormInstanceApi.save(GormInstanceApi.groovy:116)
        at org.grails.datastore.gorm.GormEntity$Trait$Helper.save(GormEntity.groovy:98)
        at org.grails.datastore.gorm.GormEntity$Trait$Helper$save$5.call(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
        at UserManage.User.save(User.groovy)
        at UserManage.User.save(User.groovy)
        at org.grails.datastore.gorm.GormEntity$save$0.call(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
        at groovy.Factories.UserFactory.Build(UserFactory.groovy:18)
        at groovy.Factories.UserFactory$Build.call(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
        at agripedia.BootStrap$_closure1.doCall(BootStrap.groovy:24)
        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.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1426)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1089)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024)
        at groovy.lang.Closure.call(Closure.java:414)
        at groovy.lang.Closure.call(Closure.java:408)
        at grails.util.Environment.evaluateEnvironmentSpecificBlock(Environment.java:516)
        at grails.util.Environment.executeForEnvironment(Environment.java:509)
        at grails.util.Environment.executeForCurrentEnvironment(Environment.java:485)
        at org.grails.web.servlet.boostrap.DefaultGrailsBootstrapClass.callInit(DefaultGrailsBootstrapClass.java:62)
        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:256)
        at grails.boot.config.GrailsApplicationPostProcessor.onApplicationEvent(GrailsApplicationPostProcessor.groovy)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:166)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:138)
        at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:383)
        at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:337)
        at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:882)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:144)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:545)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:371)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:83)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:387)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:374)
        at grails.boot.GrailsApp$run.call(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133)
        at agripedia.Application.main(Application.groovy:8)

Метод сохранения не работает, и это не связано с ошибками проверки.

Моя структура класса — это APEntity как абстрактный класс, а класс User наследуется от класса APEntity. Этот код отлично работает в Grails 2.4.4.

Буду очень признателен за любые предложения, где я могу найти, чтобы исправить ошибку.


person Abraham    schedule 10.01.2017    source источник
comment
Кажется, это связано с ограничением. Есть ли у вас какая-либо пользовательская проверка в вашем суперклассе?   -  person bassmartin    schedule 10.01.2017
comment
Проверка была проблемой, я отключил все ограничения, и проблема проверки стала очевидной. Как только я это исправил, мы снова смогли продолжить.   -  person Abraham    schedule 11.01.2017


Ответы (3)


Создаваемый экземпляр класса — User, но видимый тип — UserManage.User

 at UserManage.User.save(User.groovy)

По моему опыту, Grails 3 гораздо более типобезопасен, чем Grails 2, и менее терпим к двусмысленности. Будьте откровенны: User a = new User()

person Anatoly    schedule 10.01.2017
comment
Вы правы в том, что Grails 3 гораздо менее терпим к двусмысленности, но это хорошо. Проблема оказалась проблемой проверки, а не проблемой типа, но я проверил ваше предложение, прежде чем перейти к другим планам. Спасибо за помощь. - person Abraham; 11.01.2017
comment
@AbrahamVanderLinde Полностью согласен! - person Anatoly; 11.01.2017

Оказалось, что проблема была в валидации.

Убедившись, что типы правильные, я отключил все свои ограничения. Как только ограничения были отключены, проблема проверки стала очевидной. В моей ситуации в Grails 2 я просто вводил нулевое значение для даты, которая не указана. Кажется, что в Grails 3 это не разрешено, поэтому я присвоил ему значение по умолчанию, и проблема с проверкой была устранена.

person Abraham    schedule 11.01.2017

Просто добавлю свои заметки по этой теме, так как это был пост, который заставил меня уделить много внимания неправильным аспектам, вызывающим проблему, в надежде избавить других от траты времени на попытки определить что-то, что не кажется правильно определенным.

input a null value for a date that is not specified

Это не совсем верно.

Я потратил целую вечность, пытаясь отследить, где была создана проблема, фиктивный сайт под 3.2.8, и попытался воссоздать hasMany и реальные объекты, которые имели значение nullable true. Если бы это было так, то потребовалось бы много дополнительной работы, чтобы заполнить нули там, где это не нужно, и, в конечном итоге, заполнить БД ненужными вещами и нарушить другую логику кода.

В любом случае, насколько я понимаю, эта проблема вызвана в Grails 3.2 двумя причинами:

https://github.com/grails/grails-core/issues/10428

Это было, когда объект класса предметной области имел

String aUser 

static constraints = { 
 aUser(nullable:true)
}

Вышеупомянутое уже исправлено в более поздних версиях 3.2.X.

Недавно возникла новая проблема https://github.com/grails/grails-core/issues/10600, когда объект домена имеет _underscore

String _user 

static constraints = { 
 _user(nullable:true)
}

Похоже, это нужно исправить, и мы надеемся, что оно будет исправлено в версии 3.9.

Это означает, что если у вас есть _objects, можно с уверенностью сказать, что он может сломаться под 3.2.X > - < 3.2.8 (was working in 3.1.10).

person V H    schedule 23.04.2017