Java 如何使用MapStruct内联更新不可变字段?

Java 如何使用MapStruct内联更新不可变字段?,java,mapstruct,Java,Mapstruct,我正在使用MapStruct将数据从一个bean传输到另一个bean,并且正在努力将数据复制到目标对象的不可变内部字段中。特别是内部不可变字段是番石榴多重映射: // Source.java import com.google.common.collect.LinkedHashMultimap; public class Source { private final LinkedHashMultimap<String, String> info = LinkedHashM

我正在使用MapStruct将数据从一个bean传输到另一个bean,并且正在努力将数据复制到目标对象的不可变内部字段中。特别是内部不可变字段是番石榴多重映射:

// Source.java

import com.google.common.collect.LinkedHashMultimap;

public class Source
{
    private final LinkedHashMultimap<String, String> info = LinkedHashMultimap.create();

    public LinkedHashMultimap<String, String> getInfo()
    {
        return info;
    }

}
强制复制字段会导致编译错误:

// ForcedTargetMapper.java

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.Named;

import com.google.common.collect.LinkedHashMultimap;

@Mapper
public interface ForcedTargetMapper
{

    @Named("copyMultimap")
    default void copyMultimap(final LinkedHashMultimap<String, String> sourceMap,
            @MappingTarget final LinkedHashMultimap<String, String> targetMap)
    {
        if (sourceMap != null) {
            targetMap.putAll(sourceMap);
        }
    }

    @Mapping(target = "info", qualifiedByName = "copyMultimap")
    Target toTarget(Source source);
}
这个问题有更实际的解决办法吗? 如果目标字段是Hibernate持久化集合,并且您希望就地修改它(例如:要删除已持久化的实体,请更新现有实体和/或添加新实体),则会出现相同的问题

// BasicTargetMapper.java

import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;

import com.google.common.collect.LinkedHashMultimap;

@Mapper
public interface BasicTargetMapper
{

    default void copyMultimap(final LinkedHashMultimap<String, String> sourceMap,
            @MappingTarget final LinkedHashMultimap<String, String> targetMap)
    {
        if (sourceMap != null) {
            targetMap.putAll(sourceMap);
        }
    }

    Target toTarget(Source source);
}

// Generated BasicTargetMapperImpl.java

import javax.annotation.Generated;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2020-03-10T11:43:53+0100",
    comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_221 (Oracle Corporation)"
)
public class BasicTargetMapperImpl implements BasicTargetMapper {

    @Override
    public Target toTarget(Source source) {
        if ( source == null ) {
            return null;
        }

        Target target = new Target();

        return target;
    }
}
// ForcedTargetMapper.java

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.Named;

import com.google.common.collect.LinkedHashMultimap;

@Mapper
public interface ForcedTargetMapper
{

    @Named("copyMultimap")
    default void copyMultimap(final LinkedHashMultimap<String, String> sourceMap,
            @MappingTarget final LinkedHashMultimap<String, String> targetMap)
    {
        if (sourceMap != null) {
            targetMap.putAll(sourceMap);
        }
    }

    @Mapping(target = "info", qualifiedByName = "copyMultimap")
    Target toTarget(Source source);
}
// TargetMapper.java

import org.mapstruct.AfterMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;

import com.google.common.collect.LinkedHashMultimap;

@Mapper
public interface TargetMapper
{

    default void copyMultimap(final LinkedHashMultimap<String, String> sourceMap,
            final LinkedHashMultimap<String, String> targetMap)
    {
        if (sourceMap != null) {
            targetMap.putAll(sourceMap);
        }
    }

    @AfterMapping
    default void finishCopy(final Source source, @MappingTarget final Target target)
    {
        copyMultimap(source.getInfo(), target.getInfo());
    }

    @Mapping(target = "info", ignore = true)
    Target toTarget(Source source);
}

// Generated TargetMapperImpl.java

import javax.annotation.Generated;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2020-03-10T11:55:42+0100",
    comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_221 (Oracle Corporation)"
)
public class TargetMapperImpl implements TargetMapper {

    @Override
    public Target toTarget(Source source) {
        if ( source == null ) {
            return null;
        }

        Target target = new Target();

        finishCopy( source, target );

        return target;
    }
}