|
19 | 19 | import java.beans.PropertyDescriptor;
|
20 | 20 | import java.beans.PropertyEditor;
|
21 | 21 | import java.lang.reflect.Constructor;
|
| 22 | +import java.lang.reflect.Field; |
22 | 23 | import java.lang.reflect.InvocationTargetException;
|
23 | 24 | import java.lang.reflect.Method;
|
24 | 25 | import java.lang.reflect.Modifier;
|
|
45 | 46 |
|
46 | 47 | import org.springframework.core.KotlinDetector;
|
47 | 48 | import org.springframework.core.MethodParameter;
|
| 49 | +import org.springframework.core.convert.TypeDescriptor; |
48 | 50 | import org.springframework.lang.Nullable;
|
49 | 51 | import org.springframework.util.Assert;
|
50 | 52 | import org.springframework.util.ClassUtils;
|
@@ -681,7 +683,8 @@ public static void copyProperties(Object source, Object target, String... ignore
|
681 | 683 | }
|
682 | 684 |
|
683 | 685 | /**
|
684 |
| - * Copy the property values of the given source bean into the given target bean. |
| 686 | + * Copy the property values of the given source bean into the given target bean |
| 687 | + * and ignored if |
685 | 688 | * <p>Note: The source and target classes do not have to match or even be derived
|
686 | 689 | * from each other, as long as the properties match. Any bean properties that the
|
687 | 690 | * source bean exposes but the target bean does not will silently be ignored.
|
@@ -714,17 +717,25 @@ private static void copyProperties(Object source, Object target, @Nullable Class
|
714 | 717 | if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
|
715 | 718 | PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
|
716 | 719 | if (sourcePd != null) {
|
| 720 | + Field sourcefield = ReflectionUtils.findField(source.getClass(), sourcePd.getName()); |
| 721 | + Field targetfield = ReflectionUtils.findField(target.getClass(), targetPd.getName()); |
| 722 | + |
| 723 | + TypeDescriptor sourceTypeDescriptor = new TypeDescriptor(sourcefield); |
| 724 | + TypeDescriptor targetTypeDescriptor = new TypeDescriptor(targetfield); |
| 725 | + |
717 | 726 | Method readMethod = sourcePd.getReadMethod();
|
| 727 | + |
718 | 728 | if (readMethod != null &&
|
719 |
| - ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) { |
| 729 | + ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType()) && |
| 730 | + sourceTypeDescriptor.getResolvableType().equals(targetTypeDescriptor.getResolvableType())) { |
720 | 731 | try {
|
721 | 732 | if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
|
722 | 733 | readMethod.setAccessible(true);
|
723 | 734 | }
|
724 | 735 | Object value = readMethod.invoke(source);
|
725 | 736 | if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
|
726 | 737 | writeMethod.setAccessible(true);
|
727 |
| - } |
| 738 | + } |
728 | 739 | writeMethod.invoke(target, value);
|
729 | 740 | }
|
730 | 741 | catch (Throwable ex) {
|
|
0 commit comments