javamapstructjava-17java-record

MapStruct record to record mapping does not work


I try to convert a Java record from one package to another.

@Mapper
public interface KriteriumMapper {

    KriteriumMapper INSTANCE = Mappers.getMapper(KriteriumMapper.class);
    de.model.Kriterium fromPersistenceRecord(Kriterium k);
}
package de.persistence.model.nontransactional;

public record Kriterium(String name, String crkSpaltenname) {}

To

package de.model;

public record Kriterium(String name, String crkSpaltenname) {}

But Mapstruct creates a mapper with an empty constructor for the new record, which is obviously not possible:

@Override
public de.Kriterium fromPersistenceRecord(de.persistence.model.Kriterium k) {
    if ( k == null ) {
        return null;
    }
    
    de.model.Kriterium kriterium = new de.Kriterium();
    
    return kriterium;
}

The Mapstruct version is 1.5.5.Final.

How to handle Java record-to-record mapping?

I'm expecting a mapper implementation with uses the regular all args constructor of a jave record.


Solution

  • You mix-up the package names, I have noticed you use more than 2 Kriterium classes:

    You want to double-check that the classes from the correct packages are used in the KriteriumMapper.

    Don't forget to compile with the -parameters flag to enable generating metadata for reflection on method parameters (thanks to Rob Spoor).

    Here is a minimum working sample of record-to-record mapping:

    @Mapper
    public interface KriteriumMapper {
    
        Kriterium2 fromPersistenceRecord(Kriterium k);
    }
    
    public record Kriterium(String name, String crkSpaltenname) {}
    
    public record Kriterium2(String name, String crkSpaltenname) {}
    

    Here is the generated implementation of KriteriumMapperImpl after compilation :

    @Generated(
        value = "org.mapstruct.ap.MappingProcessor",
        date = "2023-10-02T18:18:30+0700",
        comments = "version: 1.5.5.Final, compiler: javac, environment: Java 17.0.1 (Oracle Corporation)"
    )
    public class KriteriumMapperImpl implementsKriteriumMapper {
    
        @Override
        public Kriterium2 fromPersistenceRecord(Kriterium k) {
            if ( k == null ) {
                return null;
            }
    
            String name = null;
            String crkSpaltenname = null;
    
            name = k.name();
            crkSpaltenname = k.crkSpaltenname();
    
            Kriterium2 kriterium2 = new Kriterium2( name, crkSpaltenname );
    
            return kriterium2;
        }
    }