首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Mapstruct双向映射

Mapstruct双向映射
EN

Stack Overflow用户
提问于 2020-01-24 19:04:18
回答 1查看 2.4K关注 0票数 6

在下面的示例中,我有一个单独的域层和一个单独的持久化层。我使用Mapstruct进行映射,在从域到实体或从实体到域的映射中,由于双向引用总是在->无限循环场景中被调用,所以我得到了StackOverflow。在这种情况下,我如何使用Mapstruct?

代码语言:javascript
复制
class User {
  private UserProfile userProfile;
}

class UserProfile {
 private User user;
}

@Entity
class UserEntity {
  @OneToOne
  @PrimaryKeyJoinColumn
  private UserProfileEntity userProfile;
}

@Entity
class UserProfileEntity {
  @OneToOne(mappedBy = "userProfile")
  private UserEntity userEntity;
}

用于映射的类非常基础

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

UserEntity mapToEntity(User user);

User mapToDomain(UserEntity userEntity);
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-25 04:59:54

查看Mapstruct mapping with cycles示例。

您的问题的解决方案也演示了in the documentation for Context annotation

示例

一个完整的例子:https://github.com/jannis-baratheon/stackoverflow--mapstruct-mapping-graph-with-cycles

参考文献

映射器:

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

    @Mapping(target = "userProfileEntity", source = "userProfile")
    UserEntity mapToEntity(User user,
                           @Context CycleAvoidingMappingContext cycleAvoidingMappingContext);

    @InheritInverseConfiguration
    User mapToDomain(UserEntity userEntity,
                     @Context CycleAvoidingMappingContext cycleAvoidingMappingContext);

    @Mapping(target = "userEntity", source = "user")
    UserProfileEntity mapToEntity(UserProfile userProfile,
                                  @Context CycleAvoidingMappingContext cycleAvoidingMappingContext);

    @InheritInverseConfiguration
    UserProfile mapToDomain(UserProfileEntity userProfileEntity,
                            @Context CycleAvoidingMappingContext cycleAvoidingMappingContext);
}

其中CycleAvoidingMappingContext跟踪已映射的对象并重用它们,以避免堆栈溢出:

代码语言:javascript
复制
public class CycleAvoidingMappingContext {
    private final Map<Object, Object> knownInstances = new IdentityHashMap<>();

    @BeforeMapping
    public <T> T getMappedInstance(Object source,
                                   @TargetType Class<T> targetType) {
        return targetType.cast(knownInstances.get(source));
    }

    @BeforeMapping
    public void storeMappedInstance(Object source,
                                    @MappingTarget Object target) {
        knownInstances.put(source, target);
    }
}

映射器使用(映射单个对象):

代码语言:javascript
复制
UserEntity mappedUserEntity = mapper.mapToEntity(user, new CycleAvoidingMappingContext());

您还可以在映射器上添加默认方法:

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

    // (...)

    default UserEntity mapToEntity(User user) {
        return mapToEntity(user, new CycleAvoidingMappingContext());
    }

    // (...)
}
票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59895166

复制
相关文章

相似问题

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