【问题标题】:trouble binding parameters to an object and successfully save()麻烦将参数绑定到对象并成功保存()
【发布时间】:2014-08-20 19:55:05
【问题描述】:

我有一个基本的 Q/A 应用程序,但在更改答案的顺序时遇到了问题。答案通过具有unique constraintOrdinal 属性显示。

回答域

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'
    }
}

我通过表格更新序数

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

更新操作

参数绑定到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 之前的样子

在分配params 之后。请注意,answers 已从 hibernate.collection.PersistentSet 更改为 grails.web.binding.ListOrderedSet

堆栈跟踪

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() 命令时发生错误。我做错了什么,它不喜欢我的参数类型?

【问题讨论】:

  • 您是否尝试过使用 bindData() 代替 questionInstance.properties = params?例如bindData(questionInstance, params)
  • 你应该显示Question类的源代码。
  • @JoshuaMoore 与以前相同的错误。它仍然使 questinoInstance 成为 listOrderSet 而不是 persistent set
  • @JeffScottBrown 在答案域下方添加了问题域
  • 如果您将参数动态键入自定义验证器,是否会出现问题? { val, obj -&gt; 而不是 { Answer val, Question obj -&gt;?

标签: hibernate grails groovy


【解决方案1】:

最好避免与

进行数据绑定
object.properties = params

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

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

对于您的域类Answer

创建命令类为:

Class AnswerCommand {      

    String body
    Integer ordinal
    String reason

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

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

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)
}

【讨论】:

  • 期待学习使用命令对象。我听说过它们,但不知道如何使用它们。谢谢
猜你喜欢
  • 2021-05-01
  • 2018-10-22
  • 2015-07-15
  • 1970-01-01
  • 1970-01-01
  • 2013-05-24
  • 2011-02-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多