How to skip null properties when copying properties from one object to another using Spring BeanUtils

When sending data from UI to server, generally a DTO (data object) is used. But when saving to database, it must be converted to an entity which means that the values of properties from dto should be copied to the entity object.
This can be done using utility methods of BeanUtils class in Spring as:

BeanUtils.copyProperties(source, destination)

Where source is the object from which we want to copy property values and destination is the object which we want to populate.

There may be a scenario in which you are sending some selected properties in a DTO from UI to server and other properties in the DTO will be null.
Now when you are updating existing database entity with new values using copyProperties in this case then existing properties of entity will also be made null. Let’s clarify.
Suppose we have a dto of user as:

class UserDTO {
 
private String name;
 
private String address;
//getters and setters
}

Similarly we have a user class:

class User {
 
private String name;
 
private String address;
//getters and setters
}

Now if we are updating only name, then address in the dto(sent from UI) will be null and when we use copyProperties(dto, entity), this will make address as null.
To avoid this scenario, we should have a provision while copying to ignore properties which are null. Fortunately, we have a way to accomplish this in the following way:

    /**
     * Copies properties from one object to another
     * @param source
     * @destination
     * @return
     */
    public void copyNonNullProperties(Object source, Object destination){
		BeanUtils.copyProperties(source, destination,
				getNullPropertyNames(source));
    }
    /**
     * Returns an array of null properties of an object
     * @param source
     * @return
     */
    private String[] getNullPropertyNames (Object source) {
	    final BeanWrapper src = new BeanWrapperImpl(source);
	    java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
 
	    Set emptyNames = new HashSet();
	    for(java.beans.PropertyDescriptor pd : pds) {
		//check if value of this property is null then add it to the collection
	        Object srcValue = src.getPropertyValue(pd.getName());
	        if (srcValue == null) emptyNames.add(pd.getName());
	    }
	    String[] result = new String[emptyNames.size()];
	    return emptyNames.toArray(result);
	}

Let’s tweak in:

1. Beanutils belongs to org.springframework.beans package.
2. The classes of source and destination classes may not necessarily be the same.
3. Only those properties which have the same name and which have proper getters and setters will be populated into destination object. For ex. if source has a property “name” and destination has a property “firstName” then it will not be copied.
4. Overloaded version of copyProperties takes a String array which contains the names of properties to ignore while copying from source to target bean.