【问题标题】:Mapping Domain with String ID使用字符串 ID 映射域
【发布时间】:2014-10-12 19:36:36
【问题描述】:

我正在尝试使用一个表映射一个域,该表是没有 id 列的遗留数据库的一部分,所以我选择使用带有现有列之一的字符串 id 但是我得到了当我尝试创建新实例时出现此错误消息。

org.codehaus.groovy.grails.web.servlet.mvc.exceptions.CannotRedirectException 无法重定向对象 [PlanType : (unsaved)] 它不是域或没有标识符。改用显式重定向

这是域名:

class PlanType {

static hasMany = [template:Template]

String id
String name
String description
String emailId
String initialPhase
String productType

static mapping = {

version false
table 'PLAN_TYPES'

id           generator:'assigned', name:'name', type: 'string'

name         column: 'PLAN_TYPE' 
emailId      column: 'EMAIL_ID'
initialPhase column: 'INITAL_PHASE'
productType  column: 'PRODUCT_TYPE'

}

static constraints = {
    id           (bindable:true)
    description  (maxSize:100, blank:true, nullable:true)
    emailId      (maxSize:50,  blank:true, nullable:true)
    initialPhase (maxSize:250, blank:true, nullable:true)
    productType  (maxSize:20,  blank:true, nullable:true)
}       
}

这是控制器

import static org.springframework.http.HttpStatus.*
import grails.transaction.Transactional

@Transactional(readOnly = true)
class PlanTypeController {

static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]

def index(Integer max) {
    params.max = Math.min(max ?: 10, 100)
    respond PlanType.list(params), model:[planTypeInstanceCount: PlanType.count()]
}

def show(PlanType planTypeInstance) {
    respond planTypeInstance
}

def create() {
    respond new PlanType(params)
}

@Transactional
def save(PlanType planTypeInstance) {
    if (planTypeInstance == null) {
        notFound()
        return
    }

    if (planTypeInstance.hasErrors()) {
        respond planTypeInstance.errors, view:'create'
        return
    }

    planTypeInstance.save flush:true

    request.withFormat {
        form multipartForm {
            flash.message = message(code: 'default.created.message', args: [message(code: 'planTypeInstance.label', default: 'PlanType'), planTypeInstance.id])
            redirect planTypeInstance
        }
        '*' { respond planTypeInstance, [status: CREATED] }
    }
}

def edit(PlanType planTypeInstance) {
    respond planTypeInstance
}

@Transactional
def update(PlanType planTypeInstance) {
    if (planTypeInstance == null) {
        notFound()
        return
    }

    if (planTypeInstance.hasErrors()) {
        respond planTypeInstance.errors, view:'edit'
        return
    }

    planTypeInstance.save flush:true

    request.withFormat {
        form multipartForm {
            flash.message = message(code: 'default.updated.message', args: [message(code: 'PlanType.label', default: 'PlanType'), planTypeInstance.id])
            redirect planTypeInstance
        }
        '*'{ respond planTypeInstance, [status: OK] }
    }
}

@Transactional
def delete(PlanType planTypeInstance) {

    if (planTypeInstance == null) {
        notFound()
        return
    }

    planTypeInstance.delete flush:true

    request.withFormat {
        form multipartForm {
            flash.message = message(code: 'default.deleted.message', args: [message(code: 'PlanType.label', default: 'PlanType'), planTypeInstance.id])
            redirect action:"index", method:"GET"
        }
        '*'{ render status: NO_CONTENT }
    }
}

protected void notFound() {
    request.withFormat {
        form multipartForm {
            flash.message = message(code: 'default.not.found.message', args:    [message(code: 'planTypeInstance.label', default: 'PlanType'), params.id])
            redirect action: "index", method: "GET"
        }
        '*'{ render status: NOT_FOUND }
    }
}
}

有什么办法解决这个问题吗?

【问题讨论】:

    标签: spring hibernate grails mapping


    【解决方案1】:

    替换重定向 planTypeInstance

    重定向控制器:“planType”,id:planTypeInstance.id

    在两个地方保存闭包和更新闭包

    确实有效

    参考:http://grails.1312388.n4.nabble.com/CannotRedirectException-after-update-of-simple-table-td4655841.html

    【讨论】:

      【解决方案2】:

      因为你有一个自定义的 id,你需要指定它来重定向方法。

      这是来自您的控制器的修改代码段:

              request.withFormat {
              form multipartForm {
                  flash.message = message(code: 'default.created.message', args: [message(code: 'planTypeInstance.label', default: 'PlanType'), planTypeInstance.name])
                  redirect action: "show", id: planTypeInstance.name
              }
              '*' { respond planTypeInstance, [status: CREATED] }
          }
      

      【讨论】:

        【解决方案3】:

        当您决定使用 generator:'assigned' 作为 id 列时,Hibernate 允许您自己分配 id(请参阅 docs)。

        在你的控制器的保存方法中,我猜你自己并没有明确生成 id(除了这种情况,在 params 中有一个键 id 给出了一个有效值,我不认为)。正因为如此,重定向就有问题了,因为它不知道重定向到哪里,因为缺少id。

        如果你真的想重定向到新的 PlanType,你必须确定有一个适当的 id。或者,您可以像这样重定向到 index 方法:

        redirect action: 'index'
        

        【讨论】:

        • 好吧,有道理,我希望能够创建一个新实例,但就像我说的表没有 ID 列,那么在这种情况下我有什么选择?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-11
        • 1970-01-01
        • 1970-01-01
        • 2012-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多