Search code examples
javaspringspring-java-configdozer

Dozer Mapper is not mapping composed nested fields


Tools/Frameworks in use:

  • JDK 1.7
  • Spring 3.2.5.RELEASE
  • Dozer 5.5.1

Class: BaseModel.java

package com.demo.model;
public class BaseModel {
  protected Long createdBy;
  protected Timestamp createdTimestamp;
  protected Long updatedBy;
  protected Timestamp updatedTimestamp;
  protected Long revision;
  // ... Getters/Setters
}

Class: Author.java

public class Author {
  private BaseModel baseModel;
  private Long id;
  private String firstName;
  private String lastName;

  // Getter of baseModel
  public BaseModel getBaseModel() {
    return baseModel == null ? new BaseModel() : baseModel;
  }
  // ... Other Getters/Setters
}

Class: BasePojo.java

package com.demo.web.pojo;
public class BasePojo {
  protected Long createdBy;
  protected Timestamp createdTimestamp;
  protected Long updatedBy;
  protected Timestamp updatedTimestamp;
  protected Long revision;
  // ... Getters/Setters
}

Class: AuthorPojo.java

package com.demo.web.pojo;
public class AuthorPojo extends BasePojo {
  private Long id;
  private String firstName;
  private String lastName;
  // Getters/Setters
}

Class: SpringConfig.java

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ComponentScan("com.demo")
public class SpringConfig {

}

Class: DemoDozerMapper.java

@Component("demoDozerMapper")
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class DemoDozerMapper extends DozerBeanMapper {
  @PostConstruct
  public void init() {
  logger.info("PostConstruct called....");
    this.initMappings();
  }

  private void initMappings() {
  final BeanMappingBuilder authorMappingBuilder = new BeanMappingBuilder() {
    @Override
    protected void configure() {
      mapping(Author.class, com.demo.web.pojo.Author.class, 
           TypeMappingOptions.mapId("authorMap"),
           TypeMappingOptions.mapNull(true), TypeMappingOptions.oneWay())
                .fields("baseModel.createdBy", "createdBy")
                .fields("baseModel.createdTimestamp", "createdTimestamp")
                .fields("baseModel.updatedBy", "updatedBy")
                .fields("baseModel.updatedTimestamp", "updatedTimestamp");
            }
        };

        addMapping(authorMappingBuilder);
    }
}

Class: Demo.java

public class Demo {
  public static void main(String[] args) {
    final ApplicationContext springAppContext = new AnnotationConfigApplicationContext(SpringConfig.class);
    final Mapper dozerMapper = springAppContext.getBean("demoDozerMapper", DemoDozerMapper.class);

    final Author authorModel = new Author();
    authorModel.getBaseModel().setCreatedBy(Long.valueOf(1L));
    authorModel.getBaseModel().setCreatedTimestamp(new Timestamp(System.currentTimeMillis()));
    authorModel.setFirstName("First");
    authorModel.setLastName("Last");
    authorModel.setId(Long.valueOf(21101L));

    final com.demo.web.pojo.Author author = new com.demo.web.pojo.Author();
    dozerMapper.map(authorModel, author);
    System.out.println("Author Pojo: " + author);
  }
}

Output

Author Pojo: AuthorPojo {id=21101, firstName=First, lastName=Last, createdBy=null, createdTimestamp=null, updatedBy=null, updatedTimestamp=null, revision=null}

The fields createdTimestamp and createdBy are not mapped from model to pojo. Am I doing anything wrong? Could someone help?


Solution

  • I had another look after my comment above. As well as changing the way the baseModel is set on authorModel, you also need to ensure you're calling the mapper passing the in the id corresponding to the mapping you defined in DemoDozerMapper.java (i.e. authorMap) - see here for details on context based mapping in Dozer.

    The revised Demo.java should look like this:

    Class: Demo.java

    public class Demo {
      public static void main(String[] args) {
        final ApplicationContext springAppContext = new AnnotationConfigApplicationContext(SpringConfig.class);
        final Mapper dozerMapper = springAppContext.getBean("demoDozerMapper", DemoDozerMapper.class);
    
        final Author authorModel = new Author();
    
        // Ensure base model is set
        BaseModel baseModel = new BaseModel();
        baseModel.setCreatedBy(Long.valueOf(1L));
        baseModel.setCreatedTimestamp(new Timestamp(System.currentTimeMillis()));
        authorModel.setBaseModel(baseModel);
    
        authorModel.setFirstName("First");
        authorModel.setLastName("Last");
        authorModel.setId(Long.valueOf(21101L));
    
        final AuthorPojo author = new AuthorPojo();
    
        // Select the appropriate case to use
        dozerMapper.map(authorModel, author, "authorMap");
        System.out.println("Author Pojo: " + author);
      }
    }
    

    Revised Output

    Author Pojo: AuthorPojo [id=21101, firstName=First, lastName=Last, createdBy=1, createdTimestamp=2015-11-26 10:07:31.501, updatedBy=null, updatedTimestamp=null, revision=null]