CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-github-dozermapper--dozer-core

Java Bean to Java Bean mapper that recursively copies data from one object to another

Pending
Overview
Eval results
Files

programmatic-mapping.mddocs/

Programmatic Mapping API

Fluent Java API for defining mappings programmatically without XML configuration files, providing type-safe mapping definitions and advanced field mapping options.

Capabilities

Bean Mapping Builder Base Class

Abstract base class for creating programmatic mapping configurations.

/**
 * Programmatic builder of Dozer mappings using fluent API
 */
public abstract class BeanMappingBuilder {
    /**
     * Override this method to define your mappings using the fluent API
     */
    public abstract void configure();
    
    /**
     * Creates a mapping between two classes
     * @param typeA source class
     * @param typeB destination class
     * @param options mapping options (optional)
     * @return TypeMappingBuilder for further configuration
     */
    protected TypeMappingBuilder mapping(Class<?> typeA, Class<?> typeB, TypeMappingOption... options);
    
    /**
     * Creates a mapping between two classes by name
     * @param typeA source class name
     * @param typeB destination class name
     * @param options mapping options (optional)
     * @return TypeMappingBuilder for further configuration
     */
    protected TypeMappingBuilder mapping(String typeA, String typeB, TypeMappingOption... options);
    
    /**
     * Creates a type definition for complex type configurations
     * @param type the class type
     * @return TypeDefinition for further configuration
     */
    protected TypeDefinition type(Class<?> type);
    
    /**
     * Creates a field definition for field mapping
     * @param name field name
     * @return FieldDefinition for further configuration
     */
    protected FieldDefinition field(String name);
    
    /**
     * References the current object being mapped (useful for self-mapping)
     * @return FieldDefinition representing the current object
     */
    protected FieldDefinition this_();
}

Usage Example:

import com.github.dozermapper.core.loader.api.BeanMappingBuilder;
import com.github.dozermapper.core.loader.api.FieldsMappingOptions;

public class MyMappingsBuilder extends BeanMappingBuilder {
    @Override
    public void configure() {
        // Basic class mapping
        mapping(Person.class, PersonDto.class);
        
        // Mapping with field customizations
        mapping(User.class, UserDto.class)
            .fields("firstName", "fname")
            .fields("lastName", "lname")
            .fields("birthDate", "dateOfBirth", 
                   FieldsMappingOptions.customConverter(DateToStringConverter.class));
        
        // Exclude specific fields
        mapping(Product.class, ProductDto.class)
            .exclude("internalId");
    }
}

Type Mapping Builder Interface

Interface for configuring class-level mapping options.

/**
 * Interface for configuring class-to-class mapping options
 */
public interface TypeMappingBuilder {
    /**
     * Maps fields between source and destination
     * @param sourceField source field name
     * @param destinationField destination field name
     * @return TypeMappingBuilder for method chaining
     */
    TypeMappingBuilder fields(String sourceField, String destinationField);
    
    /**
     * Maps fields with additional options
     * @param sourceField source field name
     * @param destinationField destination field name
     * @param options field mapping options
     * @return TypeMappingBuilder for method chaining
     */
    TypeMappingBuilder fields(String sourceField, String destinationField, FieldsMappingOptions... options);
    
    /**
     * Maps field using FieldDefinition objects
     * @param sourceField source field definition
     * @param destinationField destination field definition
     * @param options field mapping options
     * @return TypeMappingBuilder for method chaining
     */
    TypeMappingBuilder fields(FieldDefinition sourceField, FieldDefinition destinationField, FieldsMappingOptions... options);
    
    /**
     * Excludes a field from mapping
     * @param fieldName field name to exclude
     * @return TypeMappingBuilder for method chaining
     */
    TypeMappingBuilder exclude(String fieldName);
}

Field Definition Interface

Interface for defining complex field references and transformations.

/**
 * Interface for defining field references and transformations
 */
public interface FieldDefinition {
    /**
     * Accesses a nested field
     * @param fieldName nested field name
     * @return FieldDefinition for the nested field
     */
    FieldDefinition field(String fieldName);
    
    /**
     * Accesses an indexed element (for arrays/collections)
     * @param index array/collection index
     * @return FieldDefinition for the indexed element
     */
    FieldDefinition index(int index);
    
    /**
     * Accesses a map key
     * @param key map key
     * @return FieldDefinition for the map value
     */
    FieldDefinition mapKey(Object key);
    
    /**
     * References the current object being mapped
     * @return FieldDefinition representing the current object
     */
    FieldDefinition this_();
}

Type Definition Interface

Interface for configuring type-specific options.

/**
 * Interface for configuring type-specific options
 */
public interface TypeDefinition {
    /**
     * Sets the bean factory for this type
     * @param beanFactory factory class
     * @return TypeDefinition for method chaining
     */
    TypeDefinition beanFactory(Class<? extends BeanFactory> beanFactory);
    
    /**
     * Sets the bean factory by name
     * @param factoryName factory name
     * @return TypeDefinition for method chaining
     */
    TypeDefinition beanFactory(String factoryName);
    
    /**
     * Sets creation strategy for this type
     * @param creationStrategy creation strategy
     * @return TypeDefinition for method chaining
     */
    TypeDefinition createMethod(String creationStrategy);
    
    /**
     * Sets map ID for this type
     * @param mapId map identifier
     * @return TypeDefinition for method chaining
     */
    TypeDefinition mapId(String mapId);
}

Field Mapping Options

Basic Field Options

/**
 * Options for configuring field mappings
 */
public class FieldsMappingOptions {
    /**
     * Uses a custom converter for the field mapping
     * @param converterClass converter class
     * @return field mapping option
     */
    public static FieldsMappingOption customConverter(Class<? extends CustomConverter> converterClass);
    
    /**
     * Uses a custom converter with ID for the field mapping
     * @param converterId converter ID
     * @return field mapping option
     */
    public static FieldsMappingOption customConverterId(String converterId);
    
    /**
     * Copies the field by reference instead of deep copying
     * @return field mapping option
     */
    public static FieldsMappingOption copyByReference();
    
    /**
     * Uses a specific date format for date field conversions
     * @param format date format string
     * @return field mapping option
     */
    public static FieldsMappingOption dateFormat(String format);
    
    /**
     * Uses conditional mapping based on source field value
     * @param condition condition expression
     * @return field mapping option
     */
    public static FieldsMappingOption condition(String condition);
}

Complete Mapping Examples

Basic Entity to DTO Mapping

public class PersonMappingsBuilder extends BeanMappingBuilder {
    @Override
    public void configure() {
        mapping(Person.class, PersonDto.class)
            .fields("firstName", "fname")
            .fields("lastName", "lname")
            .fields("dateOfBirth", "birthDate", 
                   FieldsMappingOptions.dateFormat("yyyy-MM-dd"));
    }
}

Complex Nested Object Mapping

public class OrderMappingsBuilder extends BeanMappingBuilder {
    @Override
    public void configure() {
        mapping(Order.class, OrderDto.class)
            .fields("customer.firstName", "customerName")
            .fields("orderItems[0].product.name", "firstProductName")
            .fields("shippingAddress", "deliveryAddress")
            .exclude("internalNotes");
            
        mapping(Customer.class, CustomerDto.class)
            .fields("address.street", "streetAddress")
            .fields("address.city", "cityName");
    }
}

Collection and Map Mapping

public class CollectionMappingsBuilder extends BeanMappingBuilder {
    @Override
    public void configure() {
        mapping(ProductCatalog.class, CatalogDto.class)
            .fields("products", "productList")
            .fields("categoryMap", "categories");
            
        // Configure element mapping for collections
        mapping(Product.class, ProductDto.class)
            .fields("tags[0]", "primaryTag")
            .fields("attributes", "attributeMap");
    }
}

Bidirectional Mapping

public class BidirectionalMappingsBuilder extends BeanMappingBuilder {
    @Override
    public void configure() {
        mapping(User.class, UserDto.class, TypeMappingOptions.mapId("user-to-dto"))
            .fields("profile.displayName", "userName")
            .fields("settings.theme", "preferredTheme");
            
        mapping(UserDto.class, User.class, TypeMappingOptions.mapId("dto-to-user"))
            .fields("userName", "profile.displayName")
            .fields("preferredTheme", "settings.theme");
    }
}

Custom Converter Integration

public class ConverterMappingsBuilder extends BeanMappingBuilder {
    @Override
    public void configure() {
        mapping(Transaction.class, TransactionDto.class)
            .fields("amount", "amountString", 
                   FieldsMappingOptions.customConverter(MoneyToStringConverter.class))
            .fields("timestamp", "dateTime",
                   FieldsMappingOptions.customConverter(TimestampConverter.class))
            .fields("status", "statusCode",
                   FieldsMappingOptions.customConverterId("status-converter"));
    }
}

Registration with Mapper Builder

import com.github.dozermapper.core.Mapper;
import com.github.dozermapper.core.DozerBeanMapperBuilder;

// Register programmatic mappings
Mapper mapper = DozerBeanMapperBuilder.create()
    .withMappingBuilder(new PersonMappingsBuilder())
    .withMappingBuilder(new OrderMappingsBuilder())
    .withMappingBuilder(new CollectionMappingsBuilder())
    .build();

Advanced Features

Conditional Mapping

public class ConditionalMappingsBuilder extends BeanMappingBuilder {
    @Override
    public void configure() {
        mapping(Employee.class, EmployeeDto.class)
            .fields("salary", "salaryAmount", 
                   FieldsMappingOptions.condition("salary != null && salary > 0"))
            .fields("bonus", "bonusAmount",
                   FieldsMappingOptions.condition("isEligibleForBonus == true"));
    }
}

Copy by Reference

public class ReferenceMappingsBuilder extends BeanMappingBuilder {
    @Override
    public void configure() {
        mapping(Document.class, DocumentDto.class)
            .fields("metadata", "metadata", 
                   FieldsMappingOptions.copyByReference())
            .fields("content", "documentContent");
    }
}

Deep Field Access

public class DeepFieldMappingsBuilder extends BeanMappingBuilder {
    @Override
    public void configure() {
        mapping(Invoice.class, InvoiceDto.class)
            .fields(field("customer").field("company").field("address").field("zipCode"), 
                   field("customerZip"))
            .fields(field("lineItems").index(0).field("product").field("sku"), 
                   field("firstItemSku"));
    }
}

Best Practices

Organization

  • Group related mappings in the same builder class
  • Use descriptive class names for mapping builders
  • Separate complex mappings into multiple builders

Performance

  • Prefer programmatic mappings over XML for better performance
  • Register all builders during mapper creation, not at runtime
  • Use map IDs for bidirectional mappings to avoid conflicts

Maintainability

  • Document complex field mappings with comments
  • Use constants for field names when possible
  • Test programmatic mappings thoroughly with unit tests

Supporting Types

Type Mapping Option Interface

Base interface for type-level mapping configuration options.

/**
 * Interface for type mapping configuration options
 */
public interface TypeMappingOption {
    /**
     * Applies this option to the mapping builder
     * @param fieldMappingBuilder the mapping builder to configure
     */
    void apply(DozerBuilder.MappingBuilder fieldMappingBuilder);
}

Type Mapping Options Utility

Factory class for creating type mapping options.

/**
 * Utility class for creating type mapping options
 */
public final class TypeMappingOptions {
    /**
     * Sets a map ID for the mapping
     * @param mapId unique identifier for this mapping
     * @return TypeMappingOption for map ID
     */
    public static TypeMappingOption mapId(String mapId);
    
    /**
     * Sets bidirectional mapping
     * @return TypeMappingOption for bidirectional mapping
     */
    public static TypeMappingOption oneWay();
    
    /**
     * Configures mapping direction
     * @return TypeMappingOption for mapping direction
     */
    public static TypeMappingOption mapNull(boolean mapNull);
    
    /**
     * Configures empty string mapping
     * @return TypeMappingOption for empty string handling
     */
    public static TypeMappingOption mapEmptyString(boolean mapEmptyString);
}

Fields Mapping Options Utility

Factory class for creating field-level mapping options.

/**
 * Utility class for creating field mapping options
 */
public final class FieldsMappingOptions {
    /**
     * Sets a custom converter for the field
     * @param converterClass converter class
     * @return FieldsMappingOption for custom converter
     */
    public static FieldsMappingOption customConverter(Class<? extends CustomConverter> converterClass);
    
    /**
     * Sets a custom converter by ID
     * @param converterId converter identifier
     * @return FieldsMappingOption for custom converter ID
     */
    public static FieldsMappingOption customConverterId(String converterId);
    
    /**
     * Configures copy by reference
     * @return FieldsMappingOption for copy by reference
     */
    public static FieldsMappingOption copyByReference();
    
    /**
     * Sets a condition for field mapping
     * @param condition mapping condition expression
     * @return FieldsMappingOption for conditional mapping
     */
    public static FieldsMappingOption condition(String condition);
    
    /**
     * Sets the mapping direction for this field
     * @return FieldsMappingOption for one-way mapping
     */
    public static FieldsMappingOption oneWay();
}

Install with Tessl CLI

npx tessl i tessl/maven-com-github-dozermapper--dozer-core

docs

bean-factory.md

builder-configuration.md

core-mapping.md

custom-conversion.md

event-system.md

index.md

metadata-access.md

programmatic-mapping.md

tile.json