Kotlin: problems with data classes

  • Is this an issue (and hence not a question)?

I'm trying to use MapStruct with kotlin codebase. For the most part i'm pretty successfull, but i have 2 issues that are weird and require workarounds that shouldn't be necessary.

First issue that i have is that if i try to map data class with single field i have to explicitly ignore "copy" target in mapper annotation because i'm getting warning "Unmapped target property: "copy"". When i add second field - it's no longer needed. Example:

data class SinglePropertyTest(val property: String)
data class SinglePropertyTestDto(val property: String)

data class DoublePropertyTest(val property1: String, val property2: Int)
data class DoublePropertyTestDto(val property1: String, val property2: Int)

@Mapper
interface SinglePropertyMapper {
    // this gives me warning - Unmapped target property: "copy"
    fun toDto(singlePropertyTest: SinglePropertyTest): SinglePropertyTestDto

    // this works just fine
    fun toDto(doublePropertyTest: DoublePropertyTest): DoublePropertyTestDto
}

Seconds issue is more dangerous. If class have all fields nullable with default value set to null - mapper is silently failing to map any properties (all properties in target class are null). Example:

fun main(args: Array<String>) {
    val allNullClass = AllNullClass("test", null)
    val mapper = Mappers.getMapper(AllNullMapper::class.java)
    val mappedDto = mapper.toDto(allNullClass)

    // property1 here is null !
    assert(mappedDto.property1 != null)
    assert(mappedDto.property2 == null)
}

data class AllNullClass(
    val property1: String? = null,
    val property2: Int? = null
)

data class AllNullClassDto(
    val property1: String? = null,
    val property2: Int? = null
)

@Mapper
interface AllNullMapper {
    fun toDto(allNullClass: AllNullClass): AllNullClassDto
}

Generated code looks like that:

public class AllNullMapperImpl implements AllNullMapper {

    @Override
    public AllNullClassDto toDto(AllNullClass allNullClass) {
        if ( allNullClass == null ) {
            return null;
        }

        AllNullClassDto allNullClassDto = new AllNullClassDto();

        return allNullClassDto;
    }
}

It seems like MapStruct is using the empty constructor in this case.

All in all - great library, almost perfect for my current usage!