将参数绑定到对象并成功保存()

时间:2014-08-20 19:55:06

标签: hibernate grails groovy

我有一个基本的Q / A应用程序,我有问题改变我的答案的顺序。答案通过Ordinal属性显示,该属性具有unique constraint

回答域

class Answer {

    DateTime dateCreated
    DateTime lastUpdated

    String body
    Integer ordinal
    String reason

    static belongsTo = [question: Question]

    static constraints = {
        body blank: false
        ordinal unique: 'question'
    }

    String toString() {
        "Answer: $body"
    }
}

问题域

class Question {

    DateTime dateCreated
    DateTime lastUpdated

    String body
    Answer correctAnswer
    Integer ordinal

    static belongsTo = [lesson: Lesson]
    static hasMany = [answers: Answer]

    static constraints = {
        body blank: false
        correctAnswer nullable: true,
                validator: { Answer val, Question obj ->                    
                val ? val.question == obj : true // TODO: Give this a proper error message
            }
        ordinal unique: 'lesson'
    }

    static mapping = {
        lesson lazy: true
        answers sort: 'ordinal'
    }
}

我通过表格

更新序数

form image

<g:each status="i" in="${questionInstance.answers}" var="answer">
    <input type="number" name="answers[${i}].ordinal" value="${answer?.ordinal}" />: ${answer}
</g:each>    

更新操作

params绑定到questionInstance.answers对象并更新每个答案的ordinal字段

def update(Long id, Long version) {

    def questionInstance = Question.get(id)

    questionInstance.properties = params

    if (!questionInstance.save(flush: true)) {
        render(view: "edit", model: [questionInstance: questionInstance])
        return
    }

    redirect(action: "index", id: questionInstance.id)
}

这是questionInstance.answers对象在绑定params之前的样子 before

分配params

。请注意,answers已从hibernate.collection.PersistentSet更改为grails.web.binding.ListOrderedSet

after

栈跟踪

No signature of method: edu.example.work_department.website.Question$__clinit__closure1_closure3.doCall() is applicable for argument types: (edu.example.work_department.website.Answer, edu.example.work_department.website.Question) values: [Answer: Answer 2, edu.example.work_department.website.Question : 1]
Possible solutions: doCall(edu.example.work_department.website.Answer, edu.example.work_department.website.Question), call(), call([Ljava.lang.Object;), call(java.lang.Object), call(edu.example.work_department.website.Answer, edu.example.work_department.website.Question), findAll()
The following classes appear as argument class and as parameter class, but are defined by different class loader:
edu.example.work_department.website.Answer (defined by 'java.net.URLClassLoader@689319a1' and 'groovy.lang.GroovyClassLoader@8db6e40'), edu.example.work_department.website.Question (defined by 'java.net.URLClassLoader@689319a1' and 'groovy.lang.GroovyClassLoader@8db6e40')
If one of the method suggestions matches the method you wanted to call, 
then check your class loader setup.. Stacktrace follows:
'groovy.lang.MissingMethodException: No signature of method: edu.example.work_department.website.Question$__clinit__closure1_closure3.doCall() is applicable for argument types: (edu.example.work_department.website.Answer, edu.example.work_department.website.Question) values: [Answer: Answer 2, edu.example.work_department.website.Question : 1]
Possible solutions: doCall(edu.example.work_department.website.Answer, edu.example.work_department.website.Question), call(), call([Ljava.lang.Object;), call(java.lang.Object), call(edu.example.work_department.website.Answer, edu.example.work_department.website.Question), findAll()
The following classes appear as argument class and as parameter class, but are defined by different class loader:
edu.example.work_department.website.Answer (defined by 'java.net.URLClassLoader@689319a1' and 'groovy.lang.GroovyClassLoader@8db6e40'), edu.example.work_department.website.Question (defined by 'java.net.URLClassLoader@689319a1' and 'groovy.lang.GroovyClassLoader@8db6e40')
If one of the method suggestions matches the method you wanted to call, 

点击questionInstance.save()命令时发生错误。我不知道它不喜欢我的论证类型?

1 个答案:

答案 0 :(得分:3)

最好避免与

绑定数据
object.properties = params

除此之外,您还可以使用命令类grails command class creation

您可以使用命令类对象绑定数据。

对于您的域类Answer

创建命令类为:

Class AnswerCommand {      

    String body
    Integer ordinal
    String reason

    static constraints = {
        body blank: false
        ordinal unique: 'question'
    }
}

并将params作为命令类对象读取。

def update(Long id, Long version, AnswerCommand answerCmd) {

    def questionInstance = Question.get(id)

    //questionInstance.properties = params // use the below codes.

      questionInstance.body = answerCmd.body
      questionInstance.ordinal = answerCmd.ordinal
      questionInstance.reason = answerCmd.reason

    //here you can use bindData() also. But this is for making you a clear picture.


    if (!questionInstance.save(flush: true)) {
        render(view: "edit", model: [questionInstance: questionInstance])
        return
    }

    redirect(action: "index", id: questionInstance.id)
}