Skip to main content

Mapper Layer

We now create a mapper that will manage the transformation between DTOs and entities. Place this class in the mappers package. For example, in the CompanyMapper below, the method public void map(SOContext ctx, CompanySubmitDto entry, CompanyEntity entity) maps the data from the CompanySubmitDto to the CompanyEntity using MapStruct. It also adds and maps all submitted shareholders to the company using a dedicated mapper.

CompanyMapper.java
package com.dev.registration.company.mappers;

import com.dev.registration.company.data.CompanyEntity;
import com.dev.registration.company.data.ShareholderEntity;
import com.dev.registration.company.data.dm.*;
import jakarta.enterprise.context.ApplicationScoped;

import com.strategyobject.sokit.extensions.core.context.SOContext;

@ApplicationScoped
public class CompanyMapper {

private final CompanyEntityMapper companyEntityMapper;
private final ShareholdersMapper itemEntityMapper;

public CompanyMapper(
CompanyEntityMapper companyEntityMapper, ShareholdersMapper itemEntityMapper) {
this.companyEntityMapper = companyEntityMapper;
this.itemEntityMapper = itemEntityMapper;
}

public CompanyViewDto mapView(CompanyEntity entity) {
return companyEntityMapper.mapView(entity);
}

public CompanySearchableDto mapSearchable(CompanyEntity entity) {
return companyEntityMapper.mapSearchable(entity);
}

public void map(SOContext ctx, CompanySubmitDto entry, CompanyEntity entity) {
companyEntityMapper.map(entry, entity);
itemEntityMapper.addAll(ctx, entry.getShareholders(), entity);
}

public void map(SOContext ctx, CompanyApproveDto entry, CompanyEntity entity) {
companyEntityMapper.map(entry, entity);
}

public void map(SOContext ctx, CompanyRejectDto entry, CompanyEntity entity) {
companyEntityMapper.map(entry, entity);
}

}

We also implement a mapper fo the ShareHolderEntity:

ShareholdersMapper.java
package com.dev.registration.company.mappers;

import static java.util.Optional.ofNullable;

import static com.strategyobject.sokit.extensions.core.utils.CollectionUtils.orSet;

import com.dev.registration.company.data.CompanyEntity;
import com.dev.registration.company.data.ShareholderEntity;
import com.dev.registration.company.data.dm.ShareholderEntryDto;
import jakarta.inject.Singleton;
import java.util.*;
import lombok.RequiredArgsConstructor;

import com.strategyobject.sokit.extensions.core.context.SOContext;
import com.strategyobject.sokit.extensions.core.mappers.SubEntityCollectionMapper;
import com.strategyobject.sokit.extensions.core.utils.ObjectUtils;

@Singleton
@RequiredArgsConstructor
public class ShareholdersMapper
extends SubEntityCollectionMapper<CompanyEntity, ShareholderEntity, ShareholderEntryDto> {

private final CompanyEntityMapper mapper;

@Override
public void map(SOContext ctx, ShareholderEntryDto entry, ShareholderEntity entity) {
mapper.map(entry, entity);
}
}

MapStruct Mapper Interface

Finally, we define the actual mapper interface using MapStruct:

CompanyEntityMapper.java
package com.dev.registration.company.mappers;

import static org.mapstruct.MappingConstants.ComponentModel.JAKARTA_CDI;

import com.dev.registration.company.data.CompanyEntity;
import com.dev.registration.company.data.ShareholderEntity;
import com.dev.registration.company.data.dm.*;
import org.mapstruct.*;
import org.mapstruct.control.DeepClone;
@Mapper(
componentModel = JAKARTA_CDI,
builder = @Builder(disableBuilder = true),
mappingControl = DeepClone.class)
public interface CompanyEntityMapper {

CompanyViewDto mapView(CompanyEntity entity);

CompanySearchableDto mapSearchable(CompanyEntity entity);

@Mapping(target = "shareholders", ignore = true)
void map(CompanySubmitDto entry, @MappingTarget CompanyEntity entity);

@Mapping(target = "shareholders", ignore = true)
void map(CompanyApproveDto entry, @MappingTarget CompanyEntity entity);

@Mapping(target = "shareholders", ignore = true)
void map(CompanyRejectDto entry, @MappingTarget CompanyEntity entity);

@Mapping(target = "id", ignore = true)
@Mapping(target = "parent", ignore = true)
void map(ShareholderEntryDto entry, @MappingTarget ShareholderEntity entity);
}

We ignore some fields like id and parent to avoid overriding critical values during mapping.