java BeanUtils.copyProperties 缺少深度嵌套的变量?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/956604/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 14:33:40  来源:igfitidea点击:

BeanUtils.copyProperties missing deeply nested variables?

javaapache-commons-beanutils

提问by Lancelot

I'm using BeanUtils.copyProperties to copy the entire content of one object into another that inherit from it.

我正在使用 BeanUtils.copyProperties 将一个对象的全部内容复制到从它继承的另一个对象中。

Here is the context, the domain object from which the values are copied contains a Set of objects of custom type Xref. That custom type has an embedded class with various fields of various class types.

这是上下文,从中复制值的域对象包含一组自定义类型外部参照的对象。该自定义类型有一个嵌入类,其中包含各种类类型的各种字段。

For some reason one of the field from an object encapsulated within the embedded object does not get copied over. But most everything else I need do get copied over.

由于某种原因,封装在嵌入对象中的对象的字段之一不会被复制。但我需要的大多数其他东西都会被复制。

With an example:

举个例子:

class Source {
private Set<Xref> xref;
...
}

class Xref {
...
public static class primaryKey {
...
private MyObj obj;
}
}

class MyObj {
private Integer id;
...
}

Using those names if I try to use BeanUtils.copyProperties to copy the content of a "Source" object into a "SourceExtended" object the value of source.xrefs.get(0).getPrimaryKey().getObj().getId() does not get copied over. In the original object it has a value but in the target object it's null...

如果我尝试使用 BeanUtils.copyProperties 将“Source”对象的内容复制到“SourceExtended”对象中,则使用这些名称 source.xrefs.get(0).getPrimaryKey().getObj().getId() 的值不会被复制。在原始对象中它有一个值,但在目标对象中它是空的......

Any idea why???

知道为什么吗???

Thank you.

谢谢你。

回答by

From the Javadocs:

Javadocs

Note that this method is intended to perform a "shallow copy" of the properties and so complex properties (for example, nested ones) will not be copied.

请注意,此方法旨在执行属性的“浅拷贝”,因此不会复制复杂的属性(例如,嵌套的)。

回答by HonkHonkHonk

Here's how I handle this with Spring. Might be of some help. My method is a copy of Spring's shallowCopyFieldState but allows the use of a field filter. Ignores statics and finals.

这是我如何用 Spring 处理这个问题。可能会有一些帮助。我的方法是Spring的shallowCopyFieldState的副本,但允许使用字段过滤器。忽略静态和决赛。

My method

我的方法

public static void shallowCopyFieldState(final Object src, final Object dest, final FieldFilter filter)
        throws IllegalArgumentException {
    if (src == null) {
        throw new IllegalArgumentException("Source for field copy cannot be null");
    }
    if (dest == null) {
        throw new IllegalArgumentException("Destination for field copy cannot be null");
    }
    if (!src.getClass().isAssignableFrom(dest.getClass())) {
        throw new IllegalArgumentException("Destination class [" + dest.getClass().getName()
                + "] must be same or subclass as source class [" + src.getClass().getName() + "]");
    }
    org.springframework.util.ReflectionUtils.doWithFields(src.getClass(),
            new org.springframework.util.ReflectionUtils.FieldCallback() {
                public void doWith(final Field field) throws IllegalArgumentException, IllegalAccessException {
                    org.springframework.util.ReflectionUtils.makeAccessible(field);
                    final Object srcValue = field.get(src);
                    field.set(dest, srcValue);
                }
            }, filter);
}

Spring's doWithFields:

Spring 的 doWithFields:

/**
 * Invoke the given callback on all fields in the target class,
 * going up the class hierarchy to get all declared fields.
 * @param targetClass the target class to analyze
 * @param fc the callback to invoke for each field
 * @param ff the filter that determines the fields to apply the callback to
 */
public static void doWithFields(Class targetClass, FieldCallback fc, FieldFilter ff)
        throws IllegalArgumentException {

    // Keep backing up the inheritance hierarchy.
    do {
        // Copy each field declared on this class unless it's static or file.
        Field[] fields = targetClass.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            // Skip static and final fields.
            if (ff != null && !ff.matches(fields[i])) {
                continue;
            }
            try {
                fc.doWith(fields[i]);
            }
            catch (IllegalAccessException ex) {
                throw new IllegalStateException(
                        "Shouldn't be illegal to access field '" + fields[i].getName() + "': " + ex);
            }
        }
        targetClass = targetClass.getSuperclass();
    }
    while (targetClass != null && targetClass != Object.class);
}