FieldMapper { public static <T> void copyNonDefaults(final T source, final T dest, final T vanillaObject, final UpdateAction updateAction) { copy(source, dest, vanillaObject, updateAction, CopyOption.DONT_COPY_DEFAULTS); }  static void copy(final T source, final T dest); static void copy(final T source, final T dest, final UpdateAction updateAction); static void copyNonNulls(final T source,
                                        final T dest,
                                        final UpdateAction updateAction); static void copyNonNulls(final T source,
                                        final T dest); static void copyNonDefaults(final T source,
                                           final T dest,
                                           final T vanillaObject,
                                           final UpdateAction updateAction); static void copyNonDefaults(final T source,
                                           final T dest,
                                           final T vanillaObject);  }
@Test void testDeepCopyDontCopyNullsOrDefaults() throws NoSuchFieldException, IllegalAccessException { final MyParent destParent = new MyParent(); final int nonDefaultIntValue = destParent.getChild().getMyInt() + 10; final String nonDefaultStrValue = destParent.getMyString() + "_nonDefault"; destParent.getChild().setMyInt(nonDefaultIntValue); destParent.setMyString(nonDefaultStrValue); System.out.println("parent1 " + System.identityHashCode(destParent)); System.out.println("parent1 child " + System.identityHashCode(destParent.child)); int destParentId = System.identityHashCode(destParent); int destParentChildId = System.identityHashCode(destParent.child); final MyParent sourceParent = new MyParent(); sourceParent.getChild().setMyString("nonDefault"); assertThat(destParent) .isNotEqualTo(sourceParent); assertThat(destParent.getChild()) .isNotEqualTo(sourceParent.getChild()); System.out.println("parent2 " + System.identityHashCode(sourceParent)); System.out.println("parent2 child " + System.identityHashCode(sourceParent.child)); assertThat(System.identityHashCode(destParent)) .isNotEqualTo(System.identityHashCode(sourceParent)); System.out.println("parent1: " + destParent); System.out.println("parent2: " + sourceParent); FieldMapper.copyNonDefaults( sourceParent, destParent, new MyParent()); System.out.println("parent1: " + destParent); System.out.println("parent2: " + sourceParent); System.out.println(); System.out.println("parent1 " + System.identityHashCode(destParent)); System.out.println("parent1 child " + System.identityHashCode(destParent.child)); System.out.println("parent2 " + System.identityHashCode(sourceParent)); System.out.println("parent2 child " + System.identityHashCode(sourceParent.child)); assertThat(System.identityHashCode(destParent)) .isNotEqualTo(System.identityHashCode(sourceParent)); assertThat(System.identityHashCode(destParent.child)) .isNotEqualTo(System.identityHashCode(sourceParent.child)); assertThat(destParent.myInt) .isEqualTo(sourceParent.myInt); assertThat(destParent.myString) .isEqualTo(nonDefaultStrValue); assertThat(destParent.child.myInt) .isEqualTo(nonDefaultIntValue); assertThat(destParent.child.myString) .isEqualTo(sourceParent.child.myString); assertThat(System.identityHashCode(destParent)) .isEqualTo(destParentId); assertThat(System.identityHashCode(destParent.child)) .isEqualTo(destParentChildId); }