将对象属性复制到Groovy中的另一个对象 [英] Copy object properties to another object in Groovy
问题描述
我使用了一种时髦的方式来执行此操作:
https://stackoverflow.com/a/9072974 / 4470135
所以我的代码是:
def copyProperties(source,target){
def(sProps,tProps)= [source,target] *。properties * .keySet()
def commonProps = sProps.intersect(tProps) - ['class','metaClass']
commonProps。每个{target [it] = source [it]}
}
我尝试调用一个应该将实体转换为Dto的方法:
lockquote
没有方法的签名:java.util.ArrayList.keySet ()适用于
参数类型:()values:[] \ n可能的解决方案:toSet(),
toSet(),set(int,java.lang.Object),set(int, java.lang.Object),
get(int),get(int)
UPDATE:
我的源代码是一个带有字段的可序列化bean:
private String passengerName;
@NotNull
@Size(min = 5,max = 40)
private String destination;
@NotNull
private String departureDate;
我的目标是具有相同字段的JPA实体,但带有额外的@Id字段和稍微不同的日期表示:
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
ZonedDateTime departureDate
代码正在工作,但是,有些情况可能会中断。 为了解决这个问题,使用方法调用 getProperties()来替换属性访问
属性
/ code>,这可能足以满足您的需求。为了涵盖所有情况,您需要编写特殊案例的代码(见底部)。
$ b $
def copyProperties(source,target){
def(sProps,tProps)= [source,target] *。properties * .keySet ()
def commonProps = sProps.intersect(tProps) - ['class','metaClass']
commonProps.each {target [it] = source [it]}
}
def a = new Expando()
a.foo =foo
a.bar =bar
def b = new Expando()
b.baz =baz
b.bar =old
copyProperties(a,b)
println b
导致问题的示例
如果参数有一个名为属性
的属性,我会得到同样的异常(如果值为 List
):
def c = new Expando()
c.properties = []
c.bar = bar
def d = new Expando()
d.baz = baz
d.bar =old
copyProperties(c,d)
println d
这两种情况都适用:
def copyProperties(source ,target){
def(sProps,tProps)= [source,target] *。getProperties()* .keySet()
def commonProps = sProps.intersect(tProps) - ['class',' metaClass']
commonProps.each {target [it] = source [it]}
}
不是我在这里使用了对 getProperties
的显式调用,而不是访问属性
属性。 / p>
我们仍然可以解决这个问题
def e = new Object(){
//再次导致相同的异常
def getProperties(){
return []
}
def bar = bar
}
def f = new Expando()
f.baz =baz
f.bar =old
copyProperties(e,f)
您可以修复最后一页通过显式使用metaClass e 的例子
def copyProperties(source,目标){
def(sProps,tProps)= [source,target] *。getMetaClass()*。properties * .name
def commonProps = sProps.intersect(tProps) - ['class',' metaClass']
commonProps.each {target [it] = source [it]}
}
但是,由于 f
。
处理特殊情况 这里我们给出需要特殊处理的对象;) I was using a funky way to do it suggested in:
https://stackoverflow.com/a/9072974/4470135
So my code is: What I get when I try to call a method that should convert an Entity into a Dto is: No signature of method: java.util.ArrayList.keySet() is applicable
for argument types: () values: []\nPossible solutions: toSet(),
toSet(), set(int, java.lang.Object), set(int, java.lang.Object),
get(int), get(int) UPDATE: My source is a Serializable bean with fields: My target is a JPA Entity with the same fields, but with an additional @Id field and a slightly different date representation:
The code is working, however, there are corner cases where it may break. To fix this replace the property access Working example for the original version Example causing problems If the parameters have a property called What works in both cases: Not that here I used an explicit call to We can still break this You can fix the last example for However, that will fail due to Handle special cases Here we give objects that need a special treatment what they need ;)
Note that this only works like this for groovy with 这篇关于将对象属性复制到Groovy中的另一个对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
$ pre $ def $ get b $ b $ get
$ obj.getProperties()。keySet()
}
$ b $ getProperties(Object obj){
return obj.getMetaClass()*。properties * .name
}
def copyProperties(source ,target){
def(sProps,tProps)= [source,target] .collect {getProperties(it)}
def commonProps = sProps.intersect(tProps) - ['class','metaClass' ]
commonProps.each {target [it] = source [it]}
}
请注意,这只适用于使用 @CompileDynamic
作为 getProperties
实现被调用的决定将在运行时进行。替代方案是针对所有情况使用 instanceof
进行检查。def copyProperties(source, target) {
def (sProps, tProps) = [source, target]*.properties*.keySet()
def commonProps = sProps.intersect(tProps) - ['class', 'metaClass']
commonProps.each { target[it] = source[it] }
}
private String passengerName;
@NotNull
@Size(min = 5, max = 40)
private String destination;
@NotNull
private String departureDate;
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
ZonedDateTime departureDate
properties
with the method call getProperties()
, which might be enough for your case. To cover all cases, you will need to write code for special cases (see bottom)def copyProperties(source, target) {
def (sProps, tProps) = [source, target]*.properties*.keySet()
def commonProps = sProps.intersect(tProps) - ['class', 'metaClass']
commonProps.each { target[it] = source[it] }
}
def a = new Expando()
a.foo = "foo"
a.bar = "bar"
def b = new Expando()
b.baz = "baz"
b.bar = "old"
copyProperties(a, b)
println b
properties
I get the same exception you got (if the value is a List
):def c = new Expando()
c.properties = []
c.bar = "bar"
def d = new Expando()
d.baz = "baz"
d.bar = "old"
copyProperties(c, d)
println d
def copyProperties(source, target) {
def (sProps, tProps) = [source, target]*.getProperties()*.keySet()
def commonProps = sProps.intersect(tProps) - ['class', 'metaClass']
commonProps.each { target[it] = source[it] }
}
getProperties
rather than just accessing the properties
property.def e = new Object() {
// causes same Exception again
def getProperties() {
return []
}
def bar = "bar"
}
def f = new Expando()
f.baz = "baz"
f.bar = "old"
copyProperties(e, f)
e
by using the metaClass explicitlydef copyProperties(source, target) {
def (sProps, tProps) = [source, target]*.getMetaClass()*.properties*.name
def commonProps = sProps.intersect(tProps) - ['class', 'metaClass']
commonProps.each { target[it] = source[it] }
}
f
.def getProperties(Expando obj) {
return obj.getProperties().keySet()
}
def getProperties(Object obj) {
return obj.getMetaClass()*.properties*.name
}
def copyProperties(source, target) {
def (sProps, tProps) = [source, target].collect {getProperties(it)}
def commonProps = sProps.intersect(tProps) - ['class', 'metaClass']
commonProps.each { target[it] = source[it] }
}
@CompileDynamic
as the decision which getProperties
implementation is called will be made at runtime. The alternative is a check with instanceof
for all the cases.