I have a Java bean which has a field which in turn is another bean
public class BeanOne {
   private String fieldOne;
   private BeanTwo fieldTwo;
   public String getFieldOne() {return this.fieldOne;}  
   public void setFieldOne(String fieldOne){this.fieldOne = fieldOne}
   public BeanTwo getFieldTwo() {return this.fieldTwo;}  
   public void setFieldTwo(BeanTwo fieldTwo){this.fieldTwo = fieldTwo}
}
public class BeanTwo {
   private String fieldOne;
   public String getFieldOne() {return this.fieldOne;}  
   public void setFieldOne(String fieldOne){this.fieldOne = fieldOne}
}
I am trying to pass a map to BeanUtils to try and convert the following map into BeanOne
Map beanOneMap = new HashMap<String, Object>();
beanOneMap.put("fieldOne", "fieldOneValue");
Map beanTwoMap = new HashMap<String, Object>();
beanTwoMap.put("fieldOne", "fieldOneValue");
beanOneMap.put("fieldTwo", beanTwoMap);
BeanOne beanOne = new BeanOne();
BeanUtils.populate(beanOne, beanOneMap);
But it throws an error saying - Cannot invoke BeanOne.setFieldTwo on bean class 'class Bean' - argument type mismatch - had objects of type "java.util.HashMap" but expected signature "BeanTwo"
How can I use BeanUtils to correctly populate the inner bean ?
You should use Spring's BeanWrapper class. It supports nested properties, and optionally create inner beans for you:
BeanOne one = new BeanOne();
BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(one);
wrapper.setAutoGrowNestedPaths(true);
Map<String, Object> map = new HashMap<>();
map.put("fieldOne", "fieldOneValue");
map.put("fieldTwo.fieldOne", "fieldOneValue");
wrapper.setPropertyValues(map);
assertEquals("fieldOneValue", one.getFieldOne());
BeanTwo two = one.getFieldTwo();
assertNotNull(two);
assertEquals("fieldOneValue", two.getFieldOne();
The killer feature of auto-creating inner beans is achieved thanks to wrapper.setAutoGrowNestedPaths(true). The default value is false, which means you will get a NullValueInNestedPathException if an element in the property path is null.
Here we go you can do like this....
BeanOne.java
import java.util.Map;
public class BeanOne {
    private String fieldOne;
    private Map<String,BeanTwo> fieldTwo;
    public Map<String, BeanTwo> getFieldTwo() {
        return fieldTwo;
    }
    public void setFieldTwo(Map<String, BeanTwo> fieldTwo) {
        this.fieldTwo = fieldTwo;
    }
    public String getFieldOne() {
        return this.fieldOne;
    }
    public void setFieldOne(String fieldOne) {
        this.fieldOne = fieldOne;
    }
}
BeanTwo.java
public class BeanTwo {
    private String fieldOne;
    public String getFieldOne() {
        return this.fieldOne;
    }
    public void setFieldOne(String fieldOne) {
        this.fieldOne = fieldOne;
    }
}
Tester.java
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
public class Tester {
    public static void main(String[] args) throws IllegalAccessException,
            InvocationTargetException {
        Map beanTwoMap = new HashMap();
        beanTwoMap.put("fieldOne", "fieldOne2222Value");
        Map beanOneMap = new HashMap();
        beanOneMap.put("fieldOne", "fieldOneValue");
        beanOneMap.put("fieldTwo", beanTwoMap);
        BeanOne beanOne = new BeanOne();
        BeanUtils.populate(beanOne, beanOneMap);
        System.out.println(beanOne.getFieldOne());
        System.out.println(beanOne.getFieldTwo().get("fieldOne"));
    }
}
output will be:-
fieldOneValue
fieldOne2222Value
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With