重新排序属性的值时,唯一约束违规

时间:2014-08-20 17:44:31

标签: grails groovy

我正在尝试使用ordinal属性重新排列针对给定问题的答案的顺序。由于ordinal属性的约束条件为unique,因此对于问题实例,我必须分配全新的数字以避免unique constraint violation

例如,如果一个问题有4个答案且答案的序数为1,2,3,4,我无法将序数更新为3,2,1,4。我将不得不更新它们7,6,5,8,以更改顺序。有没有办法在不违反唯一约束的情况下交换ordinal字段中的值?

形式

form image

回答域

class Answer {

    DateTime dateCreated
    DateTime lastUpdated

    String body
    Integer ordinal
    String reason

    static belongsTo = [question: Question]

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

    static mapping = {
        question lazy: true
    }

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

    Integer getNextOrdinal() {
        Integer ordinal = Answer.createCriteria().get {
            projections {
                max "ordinal"
            }
        }
        ordinal = ordinal ?: 1
        return ordinal
    }
}

问题更新控制器

def update(Long id, Long version) {

    def questionInstance = Question.get(id)

    questionInstance.properties = params

    def ordinals = params.list('ordinals')

    questionInstance.answers.eachWithIndex{ Answer answer, int i ->
        answer.ordinal = ordinals[i].toInteger()
    }        

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

    flash.message = "Question: '${questionInstance.body}' has been updated"
    flash.messageType = "success"
    redirect(action: "index", id: questionInstance.id)
}

1 个答案:

答案 0 :(得分:0)

为了理解这个错误,你需要考虑发生了什么。当您保存并刷新实例时,Hibernate会发出一系列更新。在这些更新过程中,很有可能(如您所见)更新的序数值将与在刷新期间尚未更新的现有值相冲突。

为了避免这种情况,您需要清空答案集合,然后附加更新的实例。

所以不是你现在所拥有的:

def ordinals = params.list('ordinals')

questionInstance.answers.eachWithIndex{ Answer answer, int i ->
    answer.ordinal = ordinals[i].toInteger()
}  

你需要更多的东西:

def ordinals = params.list('ordinals')
def answers = []

// collect the existing answers, and update their ordinals
questionInstance.answers.eachWithIndex{ Answer answer, int i ->
  answer.ordinal = ordinals[i].toInteger()
  answers << answer
}

// clear the collection
questionInstance.answers.clear()

// add them back in again with the updated information
answers.each { questionInstance.addToAnswers(it) }

这是我的头顶,所以用它作为你应该走的方向的一个例子。

P.S。祝大学好运!