Wiki

Clone wiki

object-translator / Home

About

The purpose of the object-translator library is to facilitate the translation of objects of different types but similar structure.

For example, if you have a web application and different layers of entities: one layer is for DB, another layer is for a controller. With the help of this library, you can perform conversions between these layers.

The configuration of translation/mapping could be defined programmatically in an intuitive way.

Usage

Add it as maven dependency:

<dependency>
  <groupId>org.bitbucket.brunneng.ot</groupId>
  <artifactId>object-translator</artifactId>
  <version>1.1.1</version>
</dependency>

The main package is org.bitbucket.brunneng.ot, look there all classes mentioned below.

Create object translator with the default configuration:

Configuration configuration = new Configuration();
ObjectTranslator objectTranslator = new ObjectTranslator(configuration);

Translate your object to object with a similar structure, for example:

// personDto is of type PersonDTO 

Person person = objectTranslator.translate(personDto, Person.class);

Or map given object to another existing object:

// person is of type Person
// personDto is of type PersonDTO 

objectTranslator.map(person, personDto);

Best practices of usage with Spring

Let's say we have PersonUpdateDTO which comes from request and we should update only those fields of person, which are not null.

Create bean, TranslationService, which will wrap out object translator:

@Service
public class TranslationService {

    private ObjectTranslator objectTranslator;

    @PostConstruct
    void init() {
        Configuration c = new Configuration();
        initPersonTranslation(c);
        objectTranslator = new ObjectTranslator(c);
    }

    void initPersonTranslation(Configuration c) {
        c.beanOfClass(PersonPatchDTO.class).translationTo(Person.class).mapOnlyNotNullProperties();
    } 

    public void map(Object source, Object destination) {
        objectTranslator.map(source, destinationClass);
    }

    public <T> T translate(Object source, Class<T> destinationClass) {
        return objectTranslator.translate(source, destinationClass);
    }
}

ObjectTranslator is threadsafe, so TranslationService can be a singleton, and no additional synchronization is required.

As you can see, all custom configuration, related to Person translation/mapping is defined in method initPersonTranslation. Use the same approach of one additional configuration method per entity for better readability.

I prefer to not declare ObjectTranslator as separate bean, because in this case custom configuration will be not in TranslationService, which is not good. It is more convenient to hold it in TranslationService.

Updated