Why is it not recommended to use BeanUtils copyProperties to copy data?

Mondo Technology Updated on 2024-01-30

In actual business development, we often encounter the assignment between object attributes such as VO, BO, PO, DTO, etc., when there are many attributes, we use get, set to assign a relatively large amount of work, so many people will choose to use the copyproperties method of Beanutils, a copy tool provided by Spring, to complete the copy of properties between objects. In this way, we can greatly reduce the amount of work we need to manually write object property assignments, so why is it not recommended to use it if it is so convenient?Here's a look at the beanutilscopyproperties data copy some common onespits

This pit can be subdivided into the following two types:

1) The type of the same property is different.

In actual development, it is very likely that the type of the same field is defined in different classes, such as id, the type defined in class A may be long, and the type defined in class B is string, in this case, if beanutilscopyproperties, the copy will fail, resulting in the corresponding field being null, and the corresponding case is as follows:

public class beanutilstest }@data@allargsconstructorclass sourcepojo@dataclass targetpojo
The corresponding result is as follows:

You can see that the copied value of the id field is null due to the inconsistency of the type.

2) The same field uses the package type and base type separately.

If you use the wrapper class and the base type respectively for a field, an exception will occur when the actual value is not passed, as shown in the following examples:

public class beanutilstest }@dataclass sourcepojo@dataclass targetpojo
In the test case, the id field uses the wrapper type and base type in the copy source and copy target, respectively, and you can see that an exception occurred during the copy below.

Note:If a Boolean property uses a base type and a wrapper type, and the property name starts with is, for example, issuccess, the copy will fail.

In business development, we may have the need to copy some fields, if some fields in the copied data have null values, but the corresponding values of the same fields that need to be copied are not null, if you directly use beanutilsCopyProperties, the null value of the copied data will overwrite the field of the copied data, causing the original data to become invalid.

The corresponding cases are as follows:

public class beanutilstest }@dataclass sourcepojo@dataclass targetpojo
The corresponding result is as follows:

You can see that the username field that originally had a value in the copy target result is overwritten with null. Although you can use beanutilsCopyProperties, with a custom convertutilsbean to copy some fields, but this is also more complicated, and it loses the use of beanutilscopyproperties makes sense of copying data, so it's not recommended.

When using beanutilsWhen copyproperties is used to copy data, if both Spring's beans package and Apache's beanutils package are introduced into the project, if the package is imported incorrectly, it is likely to cause the data copy to fail, and it is not easy to find it when troubleshooting. We usually use the copy method in the sping package, and the differences between the two are as follows:

The source object is on the left, the target object is on the right)public static void copyproperties(object source, object target) throws beansexception The source object is on the right, the target object is on the left)Public static void copyproperties(object dest, object orig) throws illegalaccessexception, invocationtargetexception
In the process of development or troubleshooting, if we look up a field value in the link (The caller didn't pass itWe may use full-text search to find its corresponding assignment method (such as set mode, build mode, etc.), but if beanutils. is used in the linkcopyproperties, it is difficult to quickly locate the place where the value is assigned, resulting in low troubleshooting efficiency.

The internal class data cannot be copied normally, and the copy cannot be successful even if the type and field name are the same, as shown below

public class beanutilstest } The following is the class information, which is directly displayed in one piece@data@tostringpublic class sourcepojo}@data@tostringpublic class targetpojo}
Here's how it works:

In the above example, there is an inner class innerclass in the copy source and copy target, although the inner class properties are the same and the class name is the same, but in different classes, so Spring will think that the properties are different, so the data will not be copied.

Here I will first review the deep copy and the light copy.

Shallow copiesRefers to the creation of a new object that has the same property value as the original object, but still shares the same reference for the property of the reference type. That is to say, in a shallow copy, when the reference attribute value of the original content changes, the reference attribute value of the copied object will also change.

Deep copyRefers to the creation of a new object with the same property values as the original object, including properties of the reference type. A deep copy recursively copies the referenced object, creating an entirely new object, so the object copied by the deep copy is completely separate from the original object.

Here's an example of what it might look like:

public class beanutilstest }@data@allargsconstructorclass card @noargsconstructor@allargsconstructor@dataclass person
Here's how it works:

Summary:Through the running results, we can find that once you modify the reference type data of the original object after copying, it will cause the value of the copied data to be abnormal, which is also difficult to troubleshoot.

beanutils.copypropertiesThe underlying layer is to obtain the set and get methods of the object through reflection, and then complete the copy of the data through get and set, which is less efficient in the overall copying.

Here's how to usebeanutils.copypropertiesIn order to make it easier to see the effect intuitively, here is an example of copying 10,000 times

public class beanutilstest system.out.println("Copy method:"+(system.currenttimemillis()-copystarttime));long setstarttime = system.currenttimemillis();for(int i = 0; i < 10000; i++)system.out.println("set method:"+(system.currenttimemillis()-setstarttime));data@allargsconstructor@noargsconstructorclass user
Here's a comparison of the efficiency results of the execution:

It can be found that the regular set and beanutilsCopyProperties, the performance gap is very large. Therefore, use beanutilscopyproperties。

That's all for using beanutilsMost of these pitfalls are relatively hidden, and it is not easy to troubleshoot problems, so it is not recommended to use beanutilscopyproperties. The deficiencies in the article are welcome to be supplemented and corrected.

Author: Jingdong Technology Sun Yangwei.

*:JD Cloud Developer Community **Please indicate**.

Related Pages