magnomp opened a new issue, #14495:
URL: https://github.com/apache/grails-core/issues/14495

   If you have a domain class that is marked with @GrailsCompileSatic and this 
class has a property with a constraint nullable: true, and if this class is 
enabled for GraphQL with a custom operation/query, then the nullable: true 
constraint behaves like nullable: false.
   
   Steps to reproduce:
   1. Create a new project (Tested with Grails 4.0.4 / 4.0.5 and their default 
gorm version)
   Add `compile "org.grails.plugins:gorm-graphql-plugin:2.0.0"` dependency
   
   2. Create a domain class, say `MyDomain` marked with `@GrailsCompileStatic` 
and a `nullable` property, like:
   ```
   @GrailsCompileStatic
   class MyDomain {
       String name
   
       static constraints = {
           name nullable: true
       }
   }
   ```
   
   3. Add a custom GraphQL mapping which defines a simple query:
   ```
   @GrailsCompileStatic
   class MyDomain {
       String name
   
       static constraints = {
           name nullable: true
       }
   
       static graphql = GraphQLMapping.build {
           query("myQuery", Integer) {
               dataFetcher(new DataFetcher() {
                   @Override
                   Object get(DataFetchingEnvironment environment) throws 
Exception {
                       return new Integer(0)
                   }
               })
           }
       }
   }
   ```
   
   _If you just put `static graphql=true` or `static graphql = 
GraphQLMapping.build {}` there's no issue._
   
   4. Now in BootStrap, you just create and save a new instance of that class 
leaving the nullable field empty, like:
   ```
   class BootStrap {
   
       def init = { servletContext ->
           new MyDomain().save(failOnError: true)
       }
       def destroy = {
       }
   }
   ```
   
   5. Now you run with `gradlew bootRun`. It is expected the instance to be 
persisted with no errors, because it has only one field, which is `null`, and 
that field allows `null`. Instead, you see a validation exception:
   ```
   grails.validation.ValidationException: Validation Error(s) occurred during 
save():
   - Field error in object 'test.MyDomain' on field 'name': rejected value 
[null]; codes 
[test.MyDomain.name.nullable.error.test.MyDomain.name,test.MyDomain.name.null
   
able.error.name,test.MyDomain.name.nullable.error.java.lang.String,test.MyDomain.name.nullable.error,myDomain.name.nullable.error.test.MyDomain.name,myDomain.name.
   
nullable.error.name,myDomain.name.nullable.error.java.lang.String,myDomain.name.nullable.error,test.MyDomain.name.nullable.test.MyDomain.name,test.MyDomain.name.nu
   
llable.name,test.MyDomain.name.nullable.java.lang.String,test.MyDomain.name.nullable,myDomain.name.nullable.test.MyDomain.name,myDomain.name.nullable.name,myDomain
   
.name.nullable.java.lang.String,myDomain.name.nullable,nullable.test.MyDomain.name,nullable.name,nullable.java.lang.String,nullable];
 arguments [name,class test.My
   Domain]; default message [O campo [{0}] da classe [{1}] nÒo pode ser vazio]
   
           at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native 
Method)
           at 
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
           at 
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
           at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
           at 
org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:80)
           at 
org.codehaus.groovy.reflection.CachedConstructor.doConstructorInvoke(CachedConstructor.java:74)
           at 
groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1732)
           at 
groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1556)
           at 
org.codehaus.groovy.runtime.InvokerHelper.invokeConstructorOf(InvokerHelper.java:1042)
           at 
org.codehaus.groovy.runtime.DefaultGroovyMethods.newInstance(DefaultGroovyMethods.java:17159)
           at 
org.grails.orm.hibernate.AbstractHibernateGormInstanceApi.save(AbstractHibernateGormInstanceApi.groovy:134)
           at 
org.grails.datastore.gorm.GormEntity$Trait$Helper.save(GormEntity.groovy:153)
           at test.MyDomain.save(MyDomain.groovy)
           at test.MyDomain.save(MyDomain.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)
           at 
testconstraintnotnull.BootStrap$_closure1.doCall(BootStrap.groovy:10)
           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.MetaClassImpl.invokeMethod(MetaClassImpl.java:1099)
           at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1041)
           at groovy.lang.Closure.call(Closure.java:405)
           at groovy.lang.Closure.call(Closure.java:399)
           at 
grails.util.Environment.evaluateEnvironmentSpecificBlock(Environment.java:594)
           at 
grails.util.Environment.executeForEnvironment(Environment.java:587)
           at 
grails.util.Environment.executeForCurrentEnvironment(Environment.java:563)
           at 
org.grails.web.servlet.boostrap.DefaultGrailsBootstrapClass.callInit(DefaultGrailsBootstrapClass.java:74)
           at 
org.grails.web.servlet.context.GrailsConfigUtils.executeGrailsBootstraps(GrailsConfigUtils.java:83)
           at 
org.grails.plugins.web.servlet.context.BootStrapClassRunner.onStartup(BootStrapClassRunner.groovy:56)
           at 
grails.boot.config.GrailsApplicationPostProcessor.onApplicationEvent(GrailsApplicationPostProcessor.groovy:269)
           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:403)
           at 
org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:360)
           at 
org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:897)
           at 
org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:162)
           at 
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:553)
           at 
org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
           at 
org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744)
           at 
org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391)
           at 
org.springframework.boot.SpringApplication.run(SpringApplication.java:312)
           at grails.boot.GrailsApp.run(GrailsApp.groovy:99)
           at grails.boot.GrailsApp.run(GrailsApp.groovy:485)
           at grails.boot.GrailsApp.run(GrailsApp.groovy:472)
           at testconstraintnotnull.Application.main(Application.groovy:11)
           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.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
   ```
   
   Now if you either remove @GrailsCompileStatic or remove the custom query or 
remove `graphql` at all, the app just runs
   
   I uploaded a semple [here](https://github.com/magnomp/TestConstraintNotNull)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to