1

我正在尝试在 CommandObject 中使用具有 3 个单端关联(产品、缺陷和解决方案)的域(订单)来执行更新,并且我收到了 3 种不同的行为:

  1. cmd.order.product 接收新值;
  2. cmd.order.defect 也接收到新值(但它稍后会导致 HibernateException);
  3. cmd.order.solution 被完全忽略;

好的,这是环境:

  • 时髦的:2.3.7
  • JVM:1.7.0_71 供应商:Oracle Corporation 操作系统:Mac OS X
  • 圣杯 2.2.4

这些是演员:

class Order {

    Product product
    Defect defect
    Solution solution

    static constraints = {
        product nullable: true        
        defect nullable: true
        solution nullable: true, validator:  { val, obj, errors ->
            if (val && !obj.defect) {
                errors.rejectValue 'solution', 'defect.dequired', [val.name] as Object[], null
            }
        }
    }
}

@Validateable
class OrderCommand {

    Order order

    static constraints = {
        order nullable:false
    }
}

class OrderController {
    ...
    def update(final OrderCommand cmd) {

        def instance = cmd.order

        println params

        log.debug "cmd.errors: '${cmd.errors}'"
        log.debug "instance.errors: '${instance.errors}'"
        log.debug "instance.product.id: '${instance.product?.id}', params.order.product.id: '${params.order?.product?.id}'"
        log.debug "instance.defect.id: '${instance.defect?.id}', params.order.defect.id: '${params.order?.defect?.id}'"
        log.debug "instance.solution.id: '${instance.solution?.id}', params.order.solution.id: '${params.order?.solution?.id}'"

        if(!cmd.hasErrors() && instance.validate()) {
           instance = instance.save validate:false, failOnError:true
           this.flashDefaultMessageUpdated Order.class
        }
    }
    ...
}

这是呈现的形式(排序..):

<form action="/foo/order/update" method="post">

    <input type="hidden" id="orderId" name="order.id" value="257132">

    <select id="product" name="order.product.id">
        <option value="null">Select…&lt;/option>
        <option value="36">PRODUCT 1</option>
        ...
    </select>

    <select id="defect" name="order.defect.id">
        <option value="null">Select…&lt;/option>
        <option value="49">DEFECT 1</option>
        ...
    </select>

    <select id="solution" name="order.solution.id">
        <option value="null">Select…&lt;/option>
        <option value="6">SOLUTION 1</option>
        ...
    </select>
    ...
</form>

现在,给定一个现有的命令,对于“实例”(哈!):

def orderInstance = Order.get 257132l
println orderInstance 
//[id:257132, product:[id:36], defect:[id:4], solution:null]

提交到'/foo/order/update'后,收到的参数有:

println params
/*
[action:update, controller:order, 
               order:[
                id:257132,
                solution.id:1, 
                solution:[id:1], 
                defect.id:49, 
                defect:[id:49], 
                product.id:31, 
                product:[id:31]
            ],
order.defect.id:49, 
order.id:257132, 
order.product.id:31, 
order.solution.id:1, 
version:33]
*/

但是对象的绑定有点奇怪,检查一下:

log.debug..
/*
//DEBUG cmd.errors: '0 errors'
//DEBUG instance.errors: '0 errors'
//DEBUG instance.product.id: '31',    params.order.product.id: '31' [OK]
//DEBUG instance.defect.id: '49',     params.order.defect.id: '49' [OK]
//DEBUG instance.solution.id: 'null', params.order.solution.id: '1' [??]
*/

也就是说,产品和缺陷新值都被正确接收,而解决方案新值被简单地忽略了。

奇怪的是,当尝试执行更新时,会抛出以下异常:

org.hibernate.HibernateException: 
identifier of an instance of com.foo.domain.Defect was altered from 4 to 49

有任何想法吗?

我已经担心我的理智了。

干杯。

4

0 回答 0