Grails / GORM中的继承和约束问题

时间:2013-11-30 22:00:57

标签: grails inheritance constraints gorm

不确定如何构建这个问题,但我看到一些我无法解释的行为......任何帮助都将受到高度赞赏。我有一个超类Form和子类DraftForm。超类对属性content(blank: false)的约束比子类content(nullable: true)更严格,我正在使用tablePerHierarchy false。域类如下。

class Form {
    String content

    static constraints = { content(blank: false) }

    static mapping = { tablePerHierarchy false }
}
class DraftForm extends Form {

    static constraints = { content(nullable: true) }
}

使用上述域模型,以下测试*通过*没有任何问题。

class DraftFormIntegrationSpec extends Specification {

    void "Testing a draft-form and a form derived from a draft-form"(){

        given: "A draft-form with invalid form-fields"          // 1
        def draftForm = new DraftForm()

        when: "The draft-form is validated"                     // 2
        assert draftForm.validate() == true

        then: "The draft-form has no error"                     // 3
        !draftForm.hasErrors()

        when: "The draft-form is saved"                         // 4
        try{
            draftForm.save()
        }catch(Exception e){
            println "Exception thrown!"
            println e.class
        }

        then: "The draft-form is not found in the database"     // 5
        draftForm.id == null

        when: "The draft-form is casted to a form"              // 6
        Form form = (Form) draftForm
        assert form.validate() == true

        then: "The form validates, and has no error"            // 7
        !form.hasErrors()
    }
}

以下是我的问题:

  • 我认为子类也继承了超类的约束。在这种情况下,即使contentnull(请参阅测试中的// 2和// 3),草稿表单如何验证正常并且没有错误?
  • 如果草稿形式验证正常,为什么我会得到一个例外(// 4)并且无法在数据库中找到草稿表格(// 5)?
  • DraftForm类型转换为Form时,它仍然可以正常验证并且没有错误(// 6和// 7),即使content }属性仍为null。这怎么可能?

    感谢您的帮助!

  • 1 个答案:

    答案 0 :(得分:0)

    请在下面找到答案

    根据Grails doc https://grails.github.io/grails-doc/3.0.x/guide/GORM.html>继承策略

    tablePerHierarchy:false 会在数据库级别的表单表中对内容应用NOT-NULL约束,因此在保存时会出现异常表单对象 NULL不允许列“CONTENT”

    1. 是的子类确实继承了超类约束,但对于相同的属性,子类约束将被赋予子类对象的优先级。因此它在// 2和// 3中验证。
    2. 异常是由于表单表中的非空列内容,因此 NULL不允许列“CONTENT”,如前所述。< / LI>
    3. 当DraftForm类型转换为Form时,它仍然是draftForm的对象(尝试form.class,你会看到“class draft.DraftForm”)因此得到了验证,如果你做了一个Form的新对象将无法通过验证,因为内容将为null。
    4. 希望这能让你更好地理解事物。