Java 如何使用MapStruct内联更新不可变字段?
我正在使用MapStruct将数据从一个bean传输到另一个bean,并且正在努力将数据复制到目标对象的不可变内部字段中。特别是内部不可变字段是番石榴多重映射: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
// 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;
}
}