Backend Development 6 min read

Mastering BO, DTO, VO, PO: When and How to Use Java Object Mapping Tools

This article clarifies the purpose of Java classes ending with “O”—BO, DTO, VO, PO—explains their proper usage in a typical front‑end/back‑end workflow, and compares mapping solutions like Spring BeanUtils and MapStruct with code examples.

Lobster Programming
Lobster Programming
Lobster Programming
Mastering BO, DTO, VO, PO: When and How to Use Java Object Mapping Tools

In modern front‑end/back‑end separated projects, Java classes whose names end with “O” (BO, DTO, VO, PO) serve distinct purposes. This article explains what each represents, when to use them, and how to map between them efficiently.

1. Distinguishing BO, DTO, VO, PO

Typical request handling flow:

The front end sends request parameters encapsulated in a DTO object.

If the business logic is simple, the controller can work directly with the DTO; for complex logic, a BO (Business Object) is created to hold business data.

Database entities are represented by PO (or DO) classes, to which the BO/DTO is mapped before persisting.

After processing, the data returned to the front end is wrapped in a VO (View Object).

2. Object‑mapping tools

2.1 Spring BeanUtils

Spring provides BeanUtils.copyProperties(dest, src) to copy matching properties between beans, reducing manual setter code. Variants allow ignoring specific properties or limiting to properties defined in the target class.

2.2 MapStruct

When property names or types differ, MapStruct generates type‑safe mappers at compile time.

Dependency configuration (Maven):

<code>&lt;dependency&gt;
    &lt;groupId&gt;org.mapstruct&lt;/groupId&gt;
    &lt;artifactId&gt;mapstruct-jdk8&lt;/artifactId&gt;
    &lt;version&gt;1.2.0.Final&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.mapstruct&lt;/groupId&gt;
    &lt;artifactId&gt;mapstruct-processor&lt;/artifactId&gt;
    &lt;version&gt;1.2.0.Final&lt;/version&gt;
&lt;/dependency&gt;</code>

Basic mapper interface:

<code>@Mapper
public interface UserConvertBasic {
    // Convert entity to VO
    UserVO toConvertVO1(User source);
    // Convert VO back to entity
    User fromConvertEntity1(UserVO1 userVO1);
}</code>

Using Spring component model:

<code>@Mapper(componentModel = "spring")
public interface UserConvertBasic {
    UserVO toConvertVO1(User source);
    User fromConvertEntity1(UserVO1 userVO1);
}</code>

When source and target property names differ, explicit mappings are required:

<code>@Mapper(componentModel = "spring")
public interface UserConvertBasic {
    @Mappings({
        @Mapping(source = "id", target = "userId"),
        @Mapping(source = "name", target = "userName")
    })
    UserV04 toConvertVo(User source);
}</code>

MapStruct is powerful and supports many advanced features; other mapping libraries such as Dozer and Orika are also available.

JavaDTOSpringMapStructObject MappingBO
Lobster Programming
Written by

Lobster Programming

Sharing insights on technical analysis and exchange, making life better through technology.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.