当前位置: 首页 > 知识库问答 >
问题:

Mapstruct双向映射

楚苏燕
2023-03-14

下面的例子中,我有一个单独的域层和一个单独的持久层。我使用Mapstruct进行映射,当从域映射到实体或从实体映射到域时,会出现堆栈溢出,因为双向引用总是被调用-

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;
}

用于映射的类非常基本

@Mapper
interface UserMapper {

UserEntity mapToEntity(User user);

User mapToDomain(UserEntity userEntity);
}

共有1个答案

卢永寿
2023-03-14

查看Mapstruct与cycles的映射示例。

上下文注释文档中还演示了问题的解决方案。

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

制图员:

@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跟踪已映射的对象并重用它们,以避免堆栈溢出:

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);
    }
}

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

UserEntity mappedUserEntity = mapper.mapToEntity(user, new CycleAvoidingMappingContext());

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

@Mapper
public interface UserMapper {

    // (...)

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

    // (...)
}
 类似资料:
  • 从数据传输对象(DTO)到具有双向一对多关联的Hibernate实体执行MapStruct映射的最佳方法是什么? 假设我们有一个,其中链接了多个类型为的评论: 相应的Hibernate实体<代码>书籍<代码>与<代码>评论<代码>有一对多关联: 请注意,本书的方法还通过调用来双向设置关联,这是Hibernate专家推荐的(例如,Thorben Janssen的“Hibernate Tips:如何映

  • 我想知道Mapstruct是否以及如何帮助映射具有双向关系的ojects(在我的情况下是一对多): 从/映射到实体会产生。(我希望这会发生)。另一方面,封闭的Mapstruct问题469和1163似乎意味着Mapstruct不会直接支持它。我尝试了这个例子: https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-

  • 我有两张桌子。后 和喜欢 在这些对象之间进行hibernate注释映射,以便在类似于Post bean的。。。。 就像豆子一样 问题 该关联是否由Post{@OneToOne}和like{@ManyToOne}正确? 获取类型是Lazy,但仍然得到依赖循环。为什么? 尝试 要删除依赖关系循环,我尝试了 {@xmltransive} {@JsonIgnore} {@JsonManagedRefere

  • 我的实体如下所示: 我的问题是: 为什么会这样,即使在我添加食谱和房子之间的联系之前没有发生? 我怎样才能修好它? 原因是什么?

  • 问题内容: 假设我有个人 和工作 提取时,我无法将Person和Job映射到其他实体。 我在做什么错? 问题答案: 您的代码应为: (尝试从工作中删除重复的列’person_id’) 或其他共享主键的方法:

  • 问题内容: 映射双向列表时,我不了解Hibernate的行为。Hibernate生成的SQL语句对我来说并不是最佳的。有人可以启发我吗? 情况如下:我有一对多的父子关系。我将此关系与双向列表映射。 根据《Hibernate注释参考指南》(第7章:与索引集合的双向关联),映射应如下所示: 但是在这种情况下,Hibernate在保留一个孩子的父母时会产生三个SQL语句: 第三条语句似乎是多余的,因为并