0

I would like to do mapping of nested object that needs value from the parent object. I could use solution mentioned here mapstruct - Propagate parent field value to collection of nested objects - either directly after mapping to set some value to the child object or to use context. But in my case I work with immutable objects.

example:

data class Worker(
    val name: String,
    val businessCard: BusinessCard? = null,
)

data class BusinessCard(
    val companyName: String,
)

data class WorkerDto(
    val name: String,
    val businessCard: BusinessCardDto? = null,
)

data class BusinessCardDto(
    val text: String, // "worker name | company name"
)

Is there a way how to directly map value without @AfterMapping modifications?

Something like this?

@Mapper(config = CustomMappingConfig::class, uses = [ComputerMapper::class])
abstract class WorkerMapper {

    @Mapping(target = "businessCard.text", expression = "java(mapBcText(worker))")
    abstract fun mapWorker(worker: Worker): WorkerDto

    protected fun mapBcText(worker: Worker) = "${worker.name} | ${worker.businessCard?.companyName}"
}

But sadly the code above generates:

    @Override
    public WorkerDto mapWorker(Worker worker) {
        if ( worker == null ) {
            return null;
        }

        String name = null;
        BusinessCardDto businessCard = null;

        name = worker.getName();
        businessCard = businessCardToBusinessCardDto( worker.getBusinessCard() );

        WorkerDto workerDto = new WorkerDto( name, businessCard );

        return workerDto;
    }

    protected BusinessCardDto businessCardToBusinessCardDto(BusinessCard businessCard) {
        if ( businessCard == null ) {
            return null;
        }

        BusinessCardDto businessCardDto = new BusinessCardDto();

        businessCardDto.setText( mapBcText(worker) ); // WORKER IS NOT ACCESSIBLE HERE

        return businessCardDto;
    }

Does anybody have an idea how to achieve this mapping?

...I also tried to create custom BusinessCard mapper, but then I cannot access the parent data (Worker) in it then...

Eduard Tomek
  • 344
  • 1
  • 7
  • How diffucult woul be to write these mappers yourself rather than use a framework? Just asking as I often see people fighting frameworks which bring some benefits and a lot of headaches. – Augusto Oct 03 '21 at 16:50
  • Yes, that is one of the possible options... but my case is more complex than this simple example... There are four levels of objects and also the inheritance of some objects (polymorphism). I was thinking about some ThreadLocal store, where I could store the higher level value... similar approach to the context, but not so nice... :( – Eduard Tomek Oct 04 '21 at 06:15

1 Answers1

1

you need to use var instead of val in your dataclass.

mapstruct don't seem to manage immutable kotlin class for the moment.

sab
  • 4,352
  • 7
  • 36
  • 60