Validation Grails使用默认值验证字段

Validation Grails使用默认值验证字段,validation,grails,grails-2.4,Validation,Grails,Grails 2.4,在从2.3.8迁移而来的Grails 2.4.3应用程序中,我们有这样一个类: @Validateable class Foo { Integer noDefault; Integer withDefault = 1; static constraints = { noDefault(nullable:false) withDefault(nullable:false) } } 该类正在使用以下映射在复杂配置机制中实例化: [

在从2.3.8迁移而来的Grails 2.4.3应用程序中,我们有这样一个类:

@Validateable
class Foo {
    Integer noDefault;
    Integer withDefault = 1;

    static constraints = {
        noDefault(nullable:false)
        withDefault(nullable:false)
    }
}
该类正在使用以下映射在复杂配置机制中实例化:

[
    noDefault: 0,
    withDefault: 2
]
事实上,这个映射是一个大映射的一部分,但是类构造函数看到了这个小映射。以前,如果我们使用不为null的默认值从配置映射中省略withDefault条目,则该类可以工作。然而,在Grails2.4.3中,它告诉我这个字段不能为null。我可以通过让它在约束中为null来修复它,但它允许将explicite值设置为null并覆盖默认值,这会在操作过程中导致问题

您知道一些保留语义和正确操作的变通方法吗


Thanx提前向您致意:Balázs

您所描述的与我预期的不一致,也与我所看到的行为不一致。位于的项目包含以下代码

测试通过时:

当我运行应用程序时,我会得到相同的行为

// grails-app/conf/BootStrap.groovy
import demo.Foo

class BootStrap {

    def init = { servletContext ->
        def map = [noDefault: 0]
        def foo = new Foo(map)

        // this prints true...
        println "Foo is valid? : ${foo.validate()}"
    }
    def destroy = {
    }
}

我希望这会有所帮助。

您确定要绑定的映射确实不包含withDefault的值吗?如果它包含一个null值,则可以解释您看到的行为。如果映射确实不包含withDefault的值,那么您描述的行为对我来说没有意义。一定还有其他一些因素没有在描述中表达出来。请参阅我在下面发布的代码,如果您能了解一个有问题的场景的细节,我将很乐意进行研究。祝你好运。在黑暗中随机拍摄,但是属性名with default会与Groovy的Map.with default方法发生冲突吗?Andrew,我觉得这不太可能。所描述的场景是,withDefault的映射中没有任何条目。即使有,这应该仍然有效,但由于withDefault甚至不在地图中,我不知道这有什么关系。您的示例有效,测试通过了我。我再次尝试了真正的应用程序,这次它成功了。原因是神秘的——我经常在JVM上看到无法解释的错误,它们甚至会重复一天。无论我如何进行grailsw清理,请删除workdir或重新启动系统。JVM已损坏,重新安装它或其他版本也没有帮助。对不起,这是个错误的问题。
// test/unit/demo/FooSpec.groovy
package demo

import spock.lang.Specification
import grails.test.mixin.TestMixin
import grails.test.mixin.support.GrailsUnitTestMixin

@TestMixin(GrailsUnitTestMixin)
class FooSpec extends Specification {

    void 'test validating default values'() {
        given:
        def map = [noDefault: 0]
        def foo = new Foo(map)

        expect:
        foo.validate()
    }
}
// grails-app/conf/BootStrap.groovy
import demo.Foo

class BootStrap {

    def init = { servletContext ->
        def map = [noDefault: 0]
        def foo = new Foo(map)

        // this prints true...
        println "Foo is valid? : ${foo.validate()}"
    }
    def destroy = {
    }
}