Grails 按值而不是参照将对象特性复制到地图

Grails 按值而不是参照将对象特性复制到地图,grails,groovy,Grails,Groovy,我不确定哪里出了问题,但在保存对象实例后,如果不更改值,我似乎无法从对象实例复制属性并将其指定给贴图 这是一个示例类: class Product { String productName String proudctDescription int quantityOnHand } 一旦表单提交并发送到我的控制器,我就可以从实例中可用的productInstance.properties映射中访问并操作这些值。我想将属性复制到另一个映射,以便在编辑期间提交值之前保留这些

我不确定哪里出了问题,但在保存对象实例后,如果不更改值,我似乎无法从对象实例复制属性并将其指定给贴图

这是一个示例类:

class Product {
    String productName
    String proudctDescription
    int quantityOnHand
}
一旦表单提交并发送到我的控制器,我就可以从实例中可用的
productInstance.properties
映射中访问并操作这些值。我想将属性复制到另一个映射,以便在编辑期间提交值之前保留这些值。假设我们正在编辑一条记录,这些是存储在数据库中的值:
productName=“My Product”
productDescription=“My Product Description”
quantityOnHand=100

我想把它们复制到:

def propertiesBefore = productInstance.properties
这不起作用,因为当我保存productInstance时,propertiesBefore中的值将更改为实例所拥有的值

所以我试了一下:

productInstance.properties.each { k,v -> propertiesBefore[k] = v }
同样的事情又发生了。我不知道如何复制的价值,似乎无论我尝试它复制的参考

编辑

根据Pawel p.的要求,这是我测试的代码:

class Product {
    String productName
    String productDescription
    int quantityOnHand
}

def productInstance = new Product(productName: "Some name", productDescription: "Desciption", quantityOnHand: 10)

def propertiesBefore = [:]
productInstance.properties.each { k,v -> propertiesBefore[k] = (v instanceof Cloneable) ? v.clone() : v }

productInstance.productName = "x"
productInstance.productDescription = "y"
productInstance.quantityOnHand = 9

println propertiesBefore.quantityOnHand // this will print the same as the one after the save() 
productInstance.save(flush:true)    
println propertiesBefore.quantityOnHand // this will print the same as the one above the save()

问题是您实际上复制了对变量的引用。要获取变量的副本,应使用。看一看:

class Product {
    String productName
    String productDescription
    int quantityOnHand
}

def productInstance = new Product(productName: "Some name", productDescription: "Desciption", quantityOnHand: 10)

def propertiesBefore = [:]
productInstance.properties.each { k,v -> propertiesBefore[k] = (v instanceof Cloneable) ? v.clone() : v }

productInstance.productName = "x"
productInstance.productDescription = "y"
productInstance.quantityOnHand = 9

println productInstance.properties
println propertiesBefore
它打印:

[quantityOnHand:9, class:class Product, productName:x, productDescription:y]
[quantityOnHand:10, class:class Product, productName:Some name, productDescription:Desciption] 

groovy使用哈希映射[:]的一个简单示例如下:

def APE = [:]
APE= [tail: 1, body: "hairy", hungry: "VERY!!!"]    

def CloneMe = APE  //*APE as clone*

def CAVEMAN = [:]    //*copy APE's values over thru mapping the clone*
CloneMe.each { key,value -> CAVEMAN[key] = (value instanceof Cloneable) ? value.clone() : value } 

println "'CloneMe': ${CloneMe}"

//change some of the clone's values for CAVEMAN
CAVEMAN.tail = 0
CAVEMAN.body = "need clothes"

println "'APE': ${APE}"
println "'CAVEMAN': ${CAVEMAN}"
输出==>

'CloneMe': [tail:1, body:hairy, hungry:VERY!!!]
'APE': [tail:1, body:hairy, hungry:VERY!!!]
'CAVEMAN': [tail:0, body:need clothes, hungry:VERY!!!]
'APE': [tail:1, body:hairy, hungry:VERY!!!]
'CAVEMAN': [tail:0, body:need clothes, hungry:VERY!!!]

在不进行克隆的情况下,也可以通过“推”第一个哈希映射来将哈希映射[:]的值复制到新的哈希映射[:]的空间,这将获得与您所期望的相同的结果(按值复制)


我刚刚尝试了这段代码,只做了一次修改,就保存了productInstance.save(flush:true)并在保存前后即时打印出quantityOnHand,该值仍然被引用而未被复制。我将代码粘贴到问题中,以确定我运行了什么。我只是很惊讶把地图从一个地方复制到另一个地方是如此重要。至少,当我循环属性时,我应该能够在不复制引用的情况下将值复制到新映射。好的,谢谢。但我不确定我是否得到了你想要达到的行为。粘贴的代码将在调用
save()
前后打印
10
-可以吗?如果不是您在
save()
之前和之后所期望的,那么
10
是产品保存和修改之前的值,对吗?(修改并保存后,
productInstance
中的值为
9
)。前面的
属性值.quantityOnHand
10
,而
productInstance.quantityOnHand
的值为
9
。您在
save()
前后打印了相同的值(
properties before.quantityOnHand
)。
'APE': [tail:1, body:hairy, hungry:VERY!!!]
'CAVEMAN': [tail:0, body:need clothes, hungry:VERY!!!]