BeanUtils.copyProperties преобразует Integer null в 0

Я заметил, что BeanUtils.copyProperties(dest, src) имеет странный побочный эффект. Все нулевые Integers (вероятно, Long, Date и т. д. тоже) преобразуются в 0 в обоих объектах: источнике (sic!) и назначении. Версия: commons-beanutils-1.7.0

Javadoc:

Скопируйте значения свойств из исходного компонента в целевой компонент для всех случаев, когда имена свойств совпадают.

Например:

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

Это может быть очень ошибочно, если исходный объект фактически изменен. Какое лучшее решение для создания «настоящей» копии объекта с нулевым значением.


person lukastymo    schedule 28.11.2011    source источник
comment
Какая версия beanUtils? У меня были некоторые проблемы с устаревшим   -  person Dewfy    schedule 28.11.2011
comment
commons-beanutils-1.7.0, добавлено в пост   -  person lukastymo    schedule 28.11.2011
comment
Итак, если я переопределю конфигурацию для конкретной функции в классе, что произойдет с экземплярами bean-utils, используемыми в другом классе. Является ли переопределение специфичным для функции или для всех функций этого класса? Пожалуйста помоги   -  person Ankush Kapoor    schedule 06.06.2018


Ответы (3)


Проверка http://commons.apache.org/beanutils/api/org/apache/commons/beanutils/ConvertUtilsBean.html указывает, что значением по умолчанию для преобразования Integer является 0. Это связано с тем, что типом назначения здесь является примитивный int или ссылочный int, а примитивному int не может быть присвоено значение null.

Вы можете переопределить преобразователь для Integer и заменить его тем, значение которого по умолчанию равно null.

ОБНОВЛЕНИЕ: использование

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

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

Взгляните на исходный код IntegerConverter — вы устанавливаете значение по умолчанию в конструкторе.

person Michael Wiles    schedule 28.11.2011
comment
Звучит как объяснение. Итак, что мне нужно сделать, это заменить/изменить этот преобразователь, чтобы он возвращал значение null - значение по умолчанию. - person lukastymo; 28.11.2011

Хорошо, я нашел этот пост

Однако между этими двумя классами есть большая разница, с которой я столкнулся при использовании этих классов: BeanUtils выполняет автоматическое преобразование типов, а PropertyUtils — нет.

Например: с BeanUtils вы можете установить свойство с двойным значением, предоставив String. BeanUtils проверит тип свойства и преобразует строку в двойную. С PropertyUtils вы всегда должны предоставлять объект-значение того же типа, что и свойство, поэтому в этом примере это значение типа double.

В этом случае автоматическое преобразование не требуется, поэтому лучше выбрать класс PropertyUtils.

person lukastymo    schedule 28.11.2011

Я использую BeanUtils 1.8.3,
вместо того, чтобы регистрировать IntegerConverter в Integer.class (и любой другой класс один за другим), как ответил Майкл
, вы можете сделать это раз и навсегда, как показано ниже:

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

Таким образом, он никогда не генерирует исключений, а Default Null

person Maxwell Cheng    schedule 17.06.2021