2

BeanUtils.copyProperties を使用して、あるオブジェクトのコンテンツ全体を、それを継承する別のオブジェクトにコピーしています。

コンテキストは次のとおりです。値のコピー元のドメイン オブジェクトには、カスタム タイプ Xref のオブジェクトのセットが含まれています。そのカスタム型には、さまざまなクラス型のさまざまなフィールドを持つ埋め込みクラスがあります。

何らかの理由で、埋め込みオブジェクト内にカプセル化されたオブジェクトのフィールドの 1 つがコピーされません。しかし、私が必要とする他のほとんどすべてがコピーされます。

例を挙げます:

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

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

class MyObj {
private Integer id;
...
}

BeanUtils.copyProperties を使用して「Source」オブジェクトのコンテンツを「SourceExtended」オブジェクトにコピーしようとする場合、これらの名前を使用して、source.xrefs.get(0).getPrimaryKey().getObj().getId() の値を取得します。コピーされません。元のオブジェクトには値がありますが、ターゲット オブジェクトでは null です...

理由は?

ありがとうございました。

4

2 に答える 2

13

Javadocから:

このメソッドは、プロパティの「浅いコピー」を実行することを目的としているため、複雑なプロパティ (ネストされたものなど) はコピーされないことに注意してください。

于 2009-06-05T15:56:33.160 に答える
3

Springでこれを処理する方法は次のとおりです。役立つかもしれません。私のメソッドはSpringのshallowCopyFieldStateのコピーですが、フィールドフィルターを使用できます。スタティックとファイナルを無視します。

私の方法

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);
}

春の 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);
}
于 2009-06-05T16:31:36.713 に答える