【问题标题】:BeanUtils.copyProperties missing deeply nested variables?BeanUtils.copyProperties 缺少深度嵌套的变量?
【发布时间】:2009-06-05 15:42:56
【问题描述】:

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

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

由于某种原因,封装在嵌入对象中的对象的字段之一不会被复制。但我需要的其他大部分内容都会被复制过来。

举个例子:

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() 不会被复制。 在原始对象中它有一个值,但在目标对象中它是空的......

知道为什么吗???

谢谢。

【问题讨论】:

    标签: java apache-commons-beanutils


    【解决方案1】:

    来自Javadocs

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

    【讨论】:

      【解决方案2】:

      这是我使用 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);
      }
      

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

      【讨论】:

        猜你喜欢
        • 2020-06-07
        • 1970-01-01
        • 1970-01-01
        • 2012-08-29
        • 1970-01-01
        • 1970-01-01
        • 2016-06-27
        • 2020-07-19
        • 1970-01-01
        相关资源
        最近更新 更多