我正在使用一种时髦的方式来建议: 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.each { target[it] = source[it] }
}
当我尝试调用应该将实体转换为Dto的方法时,我得到的是:
没有方法签名:java.util.ArrayList.keySet()适用 对于参数类型:()值:[] \ n可能的解决方案:toSet(), toSet(),set(int,java.lang.Object),set(int,java.lang.Object), get(int),get(int)
更新
我的源代码是一个Serializable 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
答案 0 :(得分:0)
代码正在运行,但是,有可能会破坏的极端情况。
要解决此问题,请使用方法调用properties
替换属性访问getProperties()
,这可能足以满足您的需求。为了涵盖所有情况,您需要编写特殊情况的代码(见底部)
原始版本的工作示例
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
的属性,我会得到相同的异常(如果值为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
的显式调用,而不仅仅是访问properties
属性。
我们仍然可以打破此
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)
您可以通过显式使用metaClass来修复e
的最后一个示例
def 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
的groovy,因为将在运行时调用getProperties
实现。替代方案是对所有案例进行instanceof
检查。
答案 1 :(得分:0)
User user = User.findById('1')
User copyUser = new User()
InvokerHelper.setProperties(copyUser, user.properties)