Recently I had to cope to the problem above of "Is there any way where I can update only the existing properties in my models class and leave others as it is?"
The aforementioned accepted answer will work fine with the drawback of having to programmatically create each one of the update terms. If you have nested classes you would end having to work with dot notation and other complex stuff.
My first intuition was to use the $set Mongo operation, create a Document from a Json that contains only the updatable fields + key, and then apply it to the collection. Although it works for a structure like the one in the example of this question, it will fail with nested classes.
The solution was to use an enhanced version of the Apache BeanUtils copyProperties. The idea is:
- Get an actual full record from the db
- Populate the update Pojo with the key and updatable data. The remaining fields should be null.
- Copy from update Pojo to actual Pojo using the enhanced version.
- Create a Document from the Pojo (code bellow using SpringMongo)
- Call update
class NullAwareBeanUtilsBean extends BeanUtilsBean {
@Override
public void copyProperty(Object dest, String name, Object value)
throws IllegalAccessException, InvocationTargetException {
if (value == null)
return;
else if(value instanceof NonNullCopy) {
Class<?> destClazz = value.getClass();
Class<?> origClazz = dest.getClass();
String className = destClazz.getSimpleName();
for(Method m : origClazz.getDeclaredMethods()) {
if(m.getReturnType().equals(destClazz)) {
copyProperties(m.invoke(dest, Collections.EMPTY_LIST.toArray()),value);
}
}
return;
}
super.copyProperty(dest, name, value);
}
}
Document document = new Document();
MongoOperations.getConverter().write(Pojo, document);
Update update = new Update();
document.forEach(update::set);
dao.updateFirst(...
A complete discussion of this approach you can find at
Copy non-null properties from one object to another using BeanUtils or similar