17

I noticed that BeanUtils.copyProperties(dest, src) has a strange side effect. All null Integers (probably Long, Date etc. too) convert to 0 in both objects: source (sic!) and destination. Version: commons-beanutils-1.7.0

javadoc:

Copy property values from the origin bean to the destination bean for all cases where the property names are the same.

For example:

class User {
   Integer age = null;
   // getters & setters
}
...
User userDest = new User();
User userSrc = new User();
BeanUtils.copyProperties(userDest, userSrc);
System.out.println(userDest.getAge()); // 0
System.out.println(userSrc.getAge()); // 0

It can be very buggy that source object is actually modified. What is the best solution to make "real" copy of object with null value.

lukastymo
  • 26,145
  • 14
  • 53
  • 66
  • Which version of beanUtils? I had some problems with obsolete – Dewfy Nov 28 '11 at 12:42
  • commons-beanutils-1.7.0, added to the post – lukastymo Nov 28 '11 at 12:44
  • So if I override the configuration for a particular function in a class, what happens to the instances of bean utils used in different class. Is the overriding specific to the function or to all the functions of that class ? Please help – Ankush Kapoor Jun 06 '18 at 07:32

3 Answers3

18

Ok I've found this post

There is however a big difference between these two classes which I came across while using these classes: BeanUtils does an automatic type conversion and PropertyUtils does not.

For example: with BeanUtils you can set a double valued property by providing a String. BeanUtils will check the type of the property and convert the String into a double. With PropertyUtils you always have to provide a value object of the same type as the property, so in this example a double.

Automatic conversion is not necessary in this case, so better choice is PropertyUtils class

Yasin Okumuş
  • 2,299
  • 7
  • 31
  • 62
lukastymo
  • 26,145
  • 14
  • 53
  • 66
17

Checking http://commons.apache.org/beanutils/api/org/apache/commons/beanutils/ConvertUtilsBean.html it indicates the default for Integer conversion is 0. This is because the destination type here is the primitive int or reference int and primitive int cannot be set to null.

You can override the converter for Integer and replace it with one whose default value is null.

UPDATE: Usage is

import org.apache.commons.beanutils.converters.IntegerConverter;

IntegerConverter converter = new IntegerConverter(null); 
BeanUtilsBean beanUtilsBean = new BeanUtilsBean();
beanUtilsBean.getConvertUtils().register(converter, Integer.class);

Take a look at the source code for IntegerConverter - you set the default value in the constructor.

Michael Wiles
  • 20,902
  • 18
  • 71
  • 101
  • Sounds like explanation. So what I need to do is replace/modify this Converter to return null - default value – lukastymo Nov 28 '11 at 12:50
0

I am using BeanUtils 1.8.3,
rather than registering IntegerConverter to Integer.class (and any other class one by one) as answered by Michael
you can do it once and for all like below:

boolean throwException=false;
boolean defaultNull=true;
int defaultArraySize=0;
BeanUtilsBean.getInstance().getConvertUtils().register(throwException,  defaultNull, defaultArraySize);

In this way, it never throw exceptions, and Default Null

Maxwell Cheng
  • 1,050
  • 10
  • 17