16 April 2009

How to merge-copy a Java bean

Problem: you have one template object and one target object. They are of the same class and is a standard Java bean. You would like to copy and merge all of the properties from the template object to the target object, but only for attributes that is null in the target.

Solution:
  public <M> void merge(M target, M destination) throws Exception {
BeanInfo beanInfo = Introspector.getBeanInfo(target.getClass());

// Iterate over all the attributes
for (PropertyDescriptor descriptor : beanInfo.getPropertyDescriptors()) {

// Only copy writable attributes
if (descriptor.getWriteMethod() != null) {
Object originalValue = descriptor.getReadMethod()
.invoke(target);

// Only copy values values where the destination values is null
if (originalValue == null) {
Object defaultValue = descriptor.getReadMethod().invoke(
destination);
descriptor.getWriteMethod().invoke(target, defaultValue);
}

}
}
}


Test code:
  @Test
public void testMerge() throws Exception {
Person templatePerson = new Person("Template", 20);
Person targetPerson = new Person("Johan", null);
merge(targetPerson, templatePerson);

assertEquals("Johan", targetPerson.getName());
assertEquals(20, targetPerson.getAge());
}

private static class Person {
private String name;
private Integer age;

public Person(String name, Integer age) {
this.name = name;
this.age = age;
}

public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getAge() {
return age;
}
}

1 comment:

  1. Hi Lennart,

    nice post however the topic could get much more complicated when

    (1) a target object that holds a property that is a List - the source object holds a List as well however has 3 more items in this list. In this case one would expect to get the additional values of this list merged as well - however this will not happen in the example above.

    (2) you want to do a "deep merge" when your Bean contains other Beans which should get merged as well.

    Cheers,
    Walt

    ReplyDelete