Quantcast
Viewing latest article 3
Browse Latest Browse All 4681

Copy Specific Fields by Using BeanUtils.copyProperties in Spring

Image may be NSFW.
Clik here to view.

1. Overview

When working with Java applications, we often need to copy data from one object to another. The Spring Framework’s BeanUtils.copyProperties is a popular choice for copying properties from one bean to another. However, the method copies all matching properties by default.

Sometimes, we need to copy specific fields, such as when the source and target objects have different structures or when we only require a subset of fields for a particular operation. To copy specific fields instead of all fields, we need to customize this behavior.

In this tutorial, we’ll explore different approaches to copying only particular fields and their examples.

2. Using the ignoreProperties Option

The copyProperties method allows a third argument, ignoreProperties, which specifies the fields that shouldn’t be copied from the source object to the target object. We can pass one or more property names as varargs to exclude (like address, age).

Here, we’ll try to copy properties from SourceBean to TargetBean:

public class SourceBean {
    private String name;
    private String address;
    private int age;
    // constructor and getters/setters here
}
public class TargetBean {
    private String name;
    private String address;
    private int age;
    // constructor and getters/setters here
}

Let’s take a look at the example below, where the third argument address passed to BeanUtils.copyProperties indicates that the address property in the sourceBean shouldn’t be copied to the targetBean:

public class BeanUtilsCopyPropertiesUnitTest {
    @Test
    public void givenObjects_whenUsingIgnoreProperties_thenCopyProperties() {
        SourceBean sourceBean = new SourceBean("Peter", 30, "LA");
        TargetBean targetBean = new TargetBean();
        BeanUtils.copyProperties(sourceBean, targetBean, "address");
        assertEquals(targetBean.getName(), sourceBean.getName());
        assertEquals(targetBean.getAge(), sourceBean.getAge());
        assertNull(targetBean.getAddress());
    }
}

In the above example, the address field in the targetBean object is null.

3. Using Custom Wrapper

We can create a utility method that allows us to mention specific fields that we want to copy. This method will wrap the BeanUtils.copyProperties and allows us to specify which fields to copy while excluding others:

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

In the example below, the goal is to copy the name and age fields from sourceBean to targetBean and exclude copying the address field:

@Test
public void givenObjects_whenUsingCustomWrapper_thenCopyProperties() {
    SourceBean sourceBean = new SourceBean("Peter", 30, "LA");
    TargetBean targetBean = new TargetBean();
    BeanUtilsCopyProperties

.copySpecifiedProperties(sourceBean, targetBean, new HashSet<>(Arrays.asList("name", "age"))); assertEquals(targetBean.getName(), sourceBean.getName()); assertEquals(targetBean.getAge(), sourceBean.getAge()); assertNull(targetBean.getAddress()); }

4. Using an Intermediate DTO Object

This approach involves creating an intermediate DTO object to filter specific fields from the source object before copying them to the target object. We’ll first copy fields from the source object to the intermediate DTO object, which is a filtered representation. Then, we copy the filtered fields from the intermediate DTO object to the target object.

Let’s take a look at the structure of the intermediate object TempDTO:

public class TempDTO {
    public String name;
    public int age;
}

Now, we’ll first copy the specific fields from the sourceBean to an instance of tempDTO, and then from tempDTO to the targetBean:

@Test
public void givenObjects_whenUsingIntermediateObject_thenCopyProperties() {
    SourceBean sourceBean = new SourceBean("Peter", 30, "LA");
    TempDTO tempDTO = new TempDTO();
    BeanUtils.copyProperties(sourceBean, tempDTO);
    TargetBean targetBean = new TargetBean();
    BeanUtils.copyProperties(tempDTO, targetBean);
    assertEquals(targetBean.getName(), sourceBean.getName());
    assertEquals(targetBean.getAge(), sourceBean.getAge());
    assertNull(targetBean.getAddress());
}

5. Conclusion

In this article, we explored various approaches to copying specific fields using BeanUtils.copyProperties in Java. The ignoreProperties parameter offers a straightforward solution, while the custom wrapper and intermediate object approaches provide greater flexibility for handling long lists of properties to ignore.

The intermediate object approach runs slightly slower because it performs two copy operations, but it ensures a clean separation of concerns, prevents unnecessary data copying, and allows flexible and selective field mapping.

As always, the code used in this article can be found over on GitHub.

The post Copy Specific Fields by Using BeanUtils.copyProperties in Spring first appeared on Baeldung.Image may be NSFW.
Clik here to view.

Viewing latest article 3
Browse Latest Browse All 4681

Trending Articles