Beanutils Copyproperties API to Ignore Null and Specific Propertie

How to ignore null values using springframework BeanUtils copyProperties?

You can create your own method to copy properties while ignoring null values.

public static String[] getNullPropertyNames (Object source) {
final BeanWrapper src = new BeanWrapperImpl(source);
java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();

Set<String> emptyNames = new HashSet<String>();
for(java.beans.PropertyDescriptor pd : pds) {
Object srcValue = src.getPropertyValue(pd.getName());
if (srcValue == null) emptyNames.add(pd.getName());
}

String[] result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}

// then use Spring BeanUtils to copy and ignore null using our function
public static void myCopyProperties(Object src, Object target) {
BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
}

Copy non-null properties from one object to another using BeanUtils or similar

I ended up using Spring BeanUtils library. Here is my working method:

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.lang.reflect.Field;
import java.util.Collection;

public class MyBeansUtil<T> {
public T copyNonNullProperties(T target, T in) {
if (in == null || target == null || target.getClass() != in.getClass()) return null;

final BeanWrapper src = new BeanWrapperImpl(in);
final BeanWrapper trg = new BeanWrapperImpl(target);

for (final Field property : target.getClass().getDeclaredFields()) {
Object providedObject = src.getPropertyValue(property.getName());
if (providedObject != null && !(providedObject instanceof Collection<?>)) {
trg.setPropertyValue(
property.getName(),
providedObject);
}
}
return target;
}
}

It works fine, but notice that it ignores fields that are collections. That's on purpose, I handle them separately.

BeanUtils.copyProperties ignoring null values

You can create a custom converter that creates a default value for null properties:

public class MyNullConverter implements Converter {
@Override
public Object convert(final Class type, final Object value) {
try {
return value == null ? type.newInstance() : value;
} catch (final InstantiationException e) {
return null;
} catch (final IllegalAccessException e) {
return null;
}
}
}

Then register it for bean classes you want default (empty) values:

ConvertUtils.register(new MyNullConverter(), Something.class);

Your code will now work. The only thing that might bug you, is that your Something gets initialized twice. Don't know if this is OK...

BTW, if you want a more fine grained control over the process: use BeanUtilsBean, PropertyUtilsBean, and ConvertUtilsBean instead.

Spring Bean copy properties ignore child's object null values

com.demo.test is my project package. if any object belongs to my package , I am doing regression to copy the value. it works.

public static String[] getNullPropertyNames (Object source, Object target) {
final BeanWrapper src = new BeanWrapperImpl(source);
final BeanWrapper targetBean = new BeanWrapperImpl(target);
java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
Set<String> emptyNames = new HashSet<String>();
for(java.beans.PropertyDescriptor pd : pds) {
Object srcValue = src.getPropertyValue(pd.getName());
if (srcValue == null) {
emptyNames.add(pd.getName());
}else {
Class<?> accessor = src.getPropertyType(pd.getName());
String cname = accessor.getCanonicalName();
if(cname.contains("com.demo.test")) {
Object targetVal = targetBean.getPropertyValue(pd.getName());
if(targetVal != null) {
BeanUtils.copyProperties(srcValue,targetVal , getNullPropertyNames(srcValue,targetVal));
emptyNames.add(pd.getName());
}
}
}
}

String[] result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}

How to ask BeanUtils to ignore null values

Apparently it looks like, there is a way to tell the ConvertUtils to not throw exceptions on null values which is achieved by calling

BeanUtilsBean.getInstance().getConvertUtils().register(false, false, 0);

org.apache.commons.beanutils copyProperties ignore fields

Apapche beanutils doesn't give an option to ignore a property while copying.
However, you can use the overloaded method that can copy a single property and repeat for all the properties that you want to copy -

public static void copyProperty(Object bean,
String name,
Object value)
throws IllegalAccessException,
InvocationTargetException

This copies the specified property value to the specified destination bean, performing any type conversion that is required.

If you use spring's BeanUtil, it has an option to ignore properties -

copyProperties(Object source, Object target, String... ignoreProperties)
Copy the property values of the given source bean into the given target bean, ignoring the given "ignoreProperties".

Copy specific fields by using BeanUtils.copyProperties?

You can use the BeanWrapper technology. Here's a sample implementation:

public static void copyProperties(Object src, Object trg, Iterable<String> props) {

BeanWrapper srcWrap = PropertyAccessorFactory.forBeanPropertyAccess(src);
BeanWrapper trgWrap = PropertyAccessorFactory.forBeanPropertyAccess(trg);

props.forEach(p -> trgWrap.setPropertyValue(p, srcWrap.getPropertyValue(p)));

}

Or, if you really, really want to use BeanUtils, here's a solution. Invert the logic, gather excludes by comparing the full property list with the includes:

public static void copyProperties2(Object src, Object trg, Set<String> props) {
String[] excludedProperties =
Arrays.stream(BeanUtils.getPropertyDescriptors(src.getClass()))
.map(PropertyDescriptor::getName)
.filter(name -> !props.contains(name))
.toArray(String[]::new);

BeanUtils.copyProperties(src, trg, excludedProperties);
}

How can I parse a string with a comma thousand separator to a number?

Yes remove the commas: