首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >利用Mapstruct映射双向关系对象

利用Mapstruct映射双向关系对象
EN

Stack Overflow用户
提问于 2019-04-12 15:51:58
回答 2查看 744关注 0票数 2

我想知道Mapstruct是否以及如何帮助映射具有双向关系的对象(在我的例子中是一对多):

代码语言:javascript
复制
public class A{
     private Set<B> listB;
}

public class B{
     private A a;
}

从实体映射/映射到实体会生成StackOverflowError。(我预计这会发生)。另一方面,封闭的Mapstruct问题4691163似乎暗示mapstruct不会直接支持它。我试过这个例子:

https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-mapping-with-cycles

但这是行不通的。无论是否应用"CycleAvoidingMappingContext“,堆栈溢出错误都保持不变。

那么如何使用循环和利用mapstruct来映射对象呢?(我希望避免完全手动映射)

EN

回答 2

Stack Overflow用户

发布于 2019-04-14 14:47:46

为了使映射正常工作,您可以尝试使用以下映射程序:

代码语言:javascript
复制
@Mapper
public interface MyMapper {

    A map(A a, @Context CycleAvoidingMappingContext context);

    Set<B> map(Set<B> b, @Context CycleAvoidingMappingContext context);

    B map(B b, @Context CycleAvoidingMappingContext context);
}

如果不存在从Set<B>映射到Set<B>的方法,则不会映射A中的集合。

票数 1
EN

Stack Overflow用户

发布于 2019-04-16 15:59:20

同时,我找到了一个解决方案:首先忽略有问题的字段,并将其映射到"AfterMapping“中。在我的例子中,我还想独立地映射子对象。在我的例子中,@Context只包含一个Boolean (boolean不工作),它告诉我进入循环的位置(startedFromPru pru是父进程):

父级映射器(包含一组许可证):

代码语言:javascript
复制
@Mapper(componentModel = "spring", uses = {DateTimeMapper.class, LicenseMapper.class, CompanyCodeMapper.class, ProductHierarchyMapper.class})
public abstract class ProductResponsibleUnitMapper {

    @Autowired
    private LicenseMapper licenseMapper;

    @Mappings({@Mapping(target = "licenses", ignore = true)})
    public abstract ProductResponsibleUnit fromEntity(ProductResponsibleUnitEntity entity, @Context Boolean startedFromPru);

    @Mappings({@Mapping(target = "licenses", ignore = true)})
    public abstract ProductResponsibleUnitEntity toEntity(ProductResponsibleUnit domain, @Context Boolean startedFromPru);

    @AfterMapping
    protected void mapLicenseEntities(ProductResponsibleUnit pru, @MappingTarget ProductResponsibleUnitEntity pruEntity, @Context Boolean startedFromPru){
        if(startedFromPru) {
            pruEntity.getLicenses().clear(); //probably not necessary
            pru.getLicenses().stream().map(license -> licenseMapper.toEntity(license, startedFromPru)).forEach(pruEntity::addLicense);
        }
    }

    @AfterMapping
    protected void mapLicenseEntities(ProductResponsibleUnitEntity pruEntity, @MappingTarget ProductResponsibleUnit pru, @Context Boolean startedFromPru){
        if(startedFromPru) {
            pru.getLicenses().clear(); //probably not necessary
            pruEntity.getLicenses().stream().map(licenseEntity -> licenseMapper.fromEntity(licenseEntity, startedFromPru)).forEach(pru::addLicense);
        }
    }

}

子级映射器:

代码语言:javascript
复制
@Mapper(componentModel = "spring", uses = { DateTimeMapper.class, CompanyCodeMapper.class, ProductHierarchyMapper.class,
        CountryCodeMapper.class })
public abstract class LicenseMapper {

    @Autowired
    private ProductResponsibleUnitMapper pruMapper;

    @Mappings({ @Mapping(source = "licenseeId", target = "licensee"), @Mapping(target = "licensor", ignore = true) })
    public abstract License fromEntity(LicenseEntity entity, @Context Boolean startedFromPru);


    @Mappings({ @Mapping(source = "licensee", target = "licenseeId"), @Mapping(target = "licensor", ignore = true) })
    public abstract LicenseEntity toEntity(License domain, @Context Boolean startedFromPru);

    @AfterMapping
    protected void mapPru(LicenseEntity licenseEntity, @MappingTarget License license,
            @Context Boolean startedFromPru) {
        //only call ProductResponsibleUnitMapper if mapping did not start from PRU -> startedFromPru is false
        if (!startedFromPru) {
            license.setLicensor(pruMapper.fromEntity(licenseEntity.getLicensor(), startedFromPru));
        }
    }

    @AfterMapping
    protected void mapPru(License license, @MappingTarget LicenseEntity licenseEntity,
            @Context Boolean startedFromPru) {
        //only call ProductResponsibleUnitMapper if mapping did not start from PRU -> startedFromPru is false
        if (!startedFromPru) {
            licenseEntity.setLicensor(pruMapper.toEntity(license.getLicensor(), startedFromPru));
        }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55646904

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档