# Auto Mapping

Auto mapping is used to reduce the amount of boiler-place code required to configure mapping between two classes.

We start with our two classes, our source class `SimpleEntity` and our destination class `SimpleEntityDisplay`.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
data class SimpleEntity(
    val id: String,
    val name: String,
    val birthDate: Date,
    val email: String,
    val telephone: String
)
```

{% endtab %}

{% tab title="Java" %}

```java
public class SimpleEntity {
    private String id;
    private String name;
    private Date birthDate;
    private String email;
    private String telephone;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getBirthDate() {
        return birthDate;
    }

    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
data class SimpleEntityDisplay(
    val id: String = "",
    val fullName: String = "",
    val birthDate: Long = 0,
    val email: String = "",
    val telephone: String = ""
)
```

{% endtab %}

{% tab title="Java" %}

```java
public class SimpleEntityDisplay {
    private String id = "";
    private String name = "";
    private long birthDate = 0;
    private String email = "";
    private String telephone = "";

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public long getBirthDate() {
        return birthDate;
    }

    public void setBirthDate(long birthDate) {
        this.birthDate = birthDate;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }
}
```

{% endtab %}
{% endtabs %}

## Auto Mapping Strategy

Auto mapping supports 3 different strategies:

**BY\_NAME\_AND\_TYPE** - When a field with the same name and type is available on both the source and destination classes. The field will be mapped automatically.

In our example the fields that will be mapped in this strategy are: `id`, `email` and `telephone`.

**BY\_NAME** - When a field with the same name is available on both the source and destination classes, not necessarily of the same type. The field will be mapped automatically using [default transformers](https://shapeshift.krud.dev/transformers#default-transformers).

{% hint style="warning" %}
When using the **BY\_NAME** strategy all fields with the same name and different types must have registered default transformers for the corresponding types. Otherwise, a runtime exception will be thrown.
{% endhint %}

In our example the fields that will be mapped in this strategy are: `id`, `email,` `telephone` and `birthDate`. **Note that a default transformer between `Date` and `Long` must be registered or a runtime exception will be thrown.**

**NONE** - The **default** strategy. Disables auto mapping completely. All mappings should be added manually.

{% hint style="info" %}
When a field is mapped manually, either in the source or destination classes, all auto mappings of that field are disabled.&#x20;
{% endhint %}

## Configuring Auto Mapping

Auto mapping is available in both DSL and annotation mapping.

### Annotations

Auto mapping can be added using the `@AutoMapping` annotation.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
@AutoMapping(SimpleEntityDisplay::class, strategy = AutoMappingStrategy.BY_NAME)
@DefaultMappingTarget(SimpleEntityDisplay::class)
data class SimpleEntity(
    val id: String,
    @MappedField(mapTo = "fullName")
    val name: String,
    val birthDate: Date,
    val email: String,
    val telephone: String
)
```

{% endtab %}

{% tab title="Java" %}

```java
@AutoMapping(target = SimpleEntityDisplay.class, strategy = AutoMappingStrategy.BY_NAME)
@DefaultMappingTarget(SimpleEntityDisplay.class)
public class SimpleEntity {
    private String id;
    @MappedField(mapTo = "fullName")
    private String name;
    private Date birthDate;
    private String email;
    private String telephone;
    // Getters and Setters...
}
```

{% endtab %}
{% endtabs %}

Two things to note:

1. The `name` field is mapped manually because it has a different name in the target class.
2. The `@AutoMapping` annotation has two attributes:
   1. `target` - If no target is added then the auto mapping will be configured to any target class. It is possible to add multiple `@AutoMapping` annotation for multiple target classes.
   2. `strategy` - The auto mapping strategy. Default value `NONE`.

### Kotlin DSL

Auto mapping can be added using the `autoMap` function.&#x20;

```kotlin
val mapper = mapper<SimpleEntity, SimpleEntityDisplay> {
    autoMap(AutoMappingStrategy.BY_NAME)
    SimpleEntity::name mappedTo SimpleEntityDisplay::fullName
}
```

`autoMap` function receives the desired auto mapping strategy. It is possible to add any manual mapping to add/change mapping behavior.

### Java Builder

Similar to the Kotlin DSL, auto mapping can be added using the `autoMap` function.&#x20;

```java
MappingDefinition mappingDefinition = new MappingDefinitionBuilder(SimpleEntity.class, SimpleEntityDisplay.class)
        .autoMap(AutoMappingStrategy.BY_NAME)
        .mapField("name", "fullName")
        .build();
```

With the builder, it is also possible to add additional manual mappings to add/change mapping behavior.
