Java Bean to Java Bean mapper that recursively copies data from one object to another
—
Fluent Java API for defining mappings programmatically without XML configuration files, providing type-safe mapping definitions and advanced field mapping options.
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");
}
}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);
}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_();
}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);
}/**
* 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);
}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"));
}
}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");
}
}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");
}
}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");
}
}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"));
}
}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();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"));
}
}public class ReferenceMappingsBuilder extends BeanMappingBuilder {
@Override
public void configure() {
mapping(Document.class, DocumentDto.class)
.fields("metadata", "metadata",
FieldsMappingOptions.copyByReference())
.fields("content", "documentContent");
}
}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"));
}
}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);
}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);
}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