Search code examples
javadozer

Dozer - Having objects converted in a list while mapping from list to list?


We are using Dozer to map entities to dto objects.

We struggle with the following: Suppose we have an A entity with one-to-many relationship to B entities. When mapping we would like to convert the field produktId (e.g. 1234) in B entity to a modified value in B Dto (e.g. 00001234).

Is it possible to have objects converted in a list while mapping from list to list?

class AEntity {

 List<BEntity> bEntities;
}

class BEntity {
 Long produktId;
}

class ADto {
 List<BDto> bDtos;
}

class BDto {
 String produktId;
}

Solution

  • As André suggests, a custom converter seems appropriate here. With the API mapping something like this should work with Dozer 5.5.1:

    import org.dozer.DozerBeanMapper;
    import org.dozer.Mapper;
    import org.dozer.loader.api.BeanMappingBuilder;
    import org.dozer.loader.api.FieldsMappingOptions;
    
    public class MappingExample {
    
        private Mapper mapper;
    
        public ADto map(AEntity aEntity) {
            return getMapper().map(aEntity, ADto.class);
        }
    
        private Mapper getMapper() {
            if (mapper == null) {
    
                BeanMappingBuilder mappingBuilder = new BeanMappingBuilder() {
                    @Override
                    protected void configure() {
                        // Or just annotate getbEntities() in AEntity 
                        // with @Mapping("bDtos")
                        mapping(AEntity.class, ADto.class)
                                .fields("bEntities", "bDtos");
    
                        // Specify custom conversion for the Long field
                        mapping(BEntity.class, BDto.class)
                          .fields("produktId", "produktId",
                            FieldsMappingOptions.customConverter(
                                    LongToStringConverter.class));
                    }
                };
    
                // Pass the custom mappings to Dozer
                DozerBeanMapper beanMapper = new DozerBeanMapper();
                beanMapper.addMapping(mappingBuilder);
                mapper = beanMapper;
            }
    
            return mapper;
        }
    }
    

    The converter might look something like this:

    import org.dozer.CustomConverter;
    
    public class LongToStringConverter implements CustomConverter {
        @Override
        public Object convert(Object existingDestFieldValue, Object srcFieldValue,
                              Class<?> destinationClass, Class<?> sourceClass) {
            if (srcFieldValue != null && srcFieldValue instanceof Long
                    && String.class.equals(destinationClass)) {
                return String.format("%04d", (Long)srcFieldValue);
            }
    
            return null;
        }
    }