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

mapstruct通过将子dto与现有子实体合并来更新映射一对多关系

景唯
2023-03-14
public class ParentEntity {

   private Long id;
   private String name;
   private List<ChildEntity> children;

   //getters/setters

}

public class ChildEntity {

    private Long id;
    private String name;
    private ParentEntity myParent;

    private String notMappedField1;
    private Long notMappedField2;

    //getters/setters

}
public class ParentDTO {

       private Long id;
       private String name;
       private List<ChildDto> children;

       //getters/setters

    }

    public class ChildDto {

        private Long id;
        private String name;
        private ParentDto myParent;

        //getters/setters

    }
   @Mapper(componentModel = "cdi", uses = {ChildMapper.class})
   public interface ParentMapper {      
       ParentDto toDto(ParentEntity entity);     
       ParentEntity toEntity(ParentDto s);      
       ParentEntity toEntity(ParentDto s, @MappingTarget ParentEntity entity);           
   }

   @Mapper(componentModel = "cdi")
   public interface ChildMapper {

       ChildDto toDto(ChildEntity entity);

       @Mapping(target = "myParent", ignore = true)
       ChildEntity toEntity(ChildDto s);

       @InheritConfiguration
       ChildEntity toEntity(ChildDto s, @MappingTarget ChildEntity entity);

   }

生成的父映射器如下所示:

@ApplicationScoped
public class ParentMapperImpl implements ParentMapper {

    @Inject
    private ChildMapper childMapper;

    @Override
    public ParentDto toDto(ParentEntity entity) {
        if ( entity == null ) {
            return null;
        }

        ParentDto parentDto = new ParentDto();

        parentDto.setId( entity.getId() );
        parentDto.setName( entity.getName() );
        parentDto.setChildren( childEntityListToChildDtoList( entity.getChildren() ) );

        return parentDto;
    }

    @Override
    public ParentEntity toEntity(ParentDto s) {
        if ( s == null ) {
            return null;
        }

        ParentEntity parentEntity = new ParentEntity();

        parentEntity.setId( s.getId() );
        parentEntity.setName( s.getName() );
        parentEntity.setChildren( childDtoListToChildEntityList( s.getChildren() ) );

        return parentEntity;
    }

    @Override
    public ParentEntity toEntity(ParentDto s, ParentEntity entity) {
        if ( s == null ) {
            return null;
        }

        entity.setId( s.getId() );
        entity.setName( s.getName() );
        if ( entity.getChildren() != null ) {
            List<ChildEntity> list = childDtoListToChildEntityList( s.getChildren() );
            if ( list != null ) {
                entity.getChildren().clear();
                entity.getChildren().addAll( list );
            }
            else {
                entity.setChildren( null );
            }
        }
        else {
            List<ChildEntity> list = childDtoListToChildEntityList( s.getChildren() );
            if ( list != null ) {
                entity.setChildren( list );
            }
        }

        return entity;
    }

    protected List<ChildDto> childEntityListToChildDtoList(List<ChildEntity> list) {
        if ( list == null ) {
            return null;
        }

        List<ChildDto> list1 = new ArrayList<ChildDto>( list.size() );
        for ( ChildEntity childEntity : list ) {
            list1.add( childMapper.toDto( childEntity ) );
        }

        return list1;
    }

    protected List<ChildEntity> childDtoListToChildEntityList(List<ChildDto> list) {
        if ( list == null ) {
            return null;
        }

        List<ChildEntity> list1 = new ArrayList<ChildEntity>( list.size() );
        for ( ChildDto childDto : list ) {
            list1.add( childMapper.toEntity( childDto ) );
        }

        return list1;
    }
}

但是当调用ParentMapper.ToEntity(ParentDto s,ParentEntity entity)时,在子映射器上调用ChildMapper.ToEntity(ChildDto s)

相反,我希望调用以下子映射器方法ChildMapper.toEntity(ChildDto s,ChildEntity entity),以合并现有的子实体(假设我们在Dto中不存在的子实体上有其他字段,我们不想丢失这些字段)。
所需的结果是以下或其他等价的结果:

@ApplicationScoped
public class ParentMapperImpl implements ParentMapper {

      ...

      @Override
      public ParentEntity toEntity(ParentDto s, ParentEntity entity) {
          if (s == null) {
              return null;
          }

          entity.setId(s.getId());
          entity.setName(s.getName());
          if (entity.getChildren() != null) {
              List<ChildEntity> list = childDtoListToChildEntityList(s.getChildren(), entity.getChildren());
              if (list != null) {
                  entity.getChildren().clear();
                  entity.getChildren().addAll(list);
              } else {
                  entity.setChildren(null);
              }
          } else {
              List<ChildEntity> list = childDtoListToChildEntityList(s.getChildren());
              if (list != null) {
                  entity.setChildren(list);
              }
          }

          return entity;
      }

      ...

      protected List<ChildEntity> childDtoListToChildEntityList(List<ChildDto> list, List<ChildEntity> entities) {
          if (list == null) {
              return null;
          }


          final List<ChildEntity> list1 = new ArrayList<ChildEntity>(list.size());
          for (ChildEntity entity : entities) {
              Optional<ChildEntity> optional = findEntity(entity.getId(), list);
              if (optional.isPresent()) {
                  list1.add(childMapper.toEntity(optional.get(), entity));
              }
          }

          list1.addAll(
                  list.stream()
                          .filter(dto -> dto.getId() == null)
                          .map(dto -> childMapper.toEntity(dto))
                          .collect(Collectors.toList())
          );


          return list1;
      }

      private Optional<ChildEntity> findEntity(Long id, List<ChildDto> list) {
          return list.stream().filter(dto -> dto.getId().equals(id)).findAny();
      }

}          

共有1个答案

卜勇
2023-03-14

我的porpouse是通过合并现有的子实体来执行一对多实体关系的更新,假设我们在Dto中不存在的子实体上有其他字段,我们不想丢失这些字段。

我有两个具有一对多关系的实体,如下所示:

public class ParentEntity {

   private Long id;
   private String name;
   private List<ChildEntity> children;

   //getters/setters

}

public class ChildEntity {

    private Long id;
    private String name;
    private ParentEntity myParent;

    private String notMappedField1;
    private Long notMappedField2;

    //getters/setters

}

和DTOs

public class ParentDTO {

       private Long id;
       private String name;
       private List<ChildDto> children;

       //getters/setters

    }

    public class ChildDto {

        private Long id;
        private String name;
        private ParentDto myParent;

        //getters/setters

    }
   @Mapper(componentModel = "cdi", uses = {ChildMapper.class})
   public interface ParentMapper {      
       ParentDto toDto(ParentEntity entity);     
       ParentEntity toEntity(ParentDto s);      
       ParentEntity toEntity(ParentDto s, @MappingTarget ParentEntity entity);           
   }

   @Mapper(componentModel = "cdi")
   public interface ChildMapper {

       ChildDto toDto(ChildEntity entity);

       @Mapping(target = "myParent", ignore = true)
       ChildEntity toEntity(ChildDto s);

       @InheritConfiguration
       ChildEntity toEntity(ChildDto s, @MappingTarget ChildEntity entity);

   }
@ApplicationScoped
public class ParentMapperImpl implements ParentMapper {

    @Inject
    private ChildMapper childMapper;

    @Override
    public ParentDto toDto(ParentEntity entity) {
        if ( entity == null ) {
            return null;
        }

        ParentDto parentDto = new ParentDto();

        parentDto.setId( entity.getId() );
        parentDto.setName( entity.getName() );
        parentDto.setChildren( childEntityListToChildDtoList( entity.getChildren() ) );

        return parentDto;
    }

    @Override
    public ParentEntity toEntity(ParentDto s) {
        if ( s == null ) {
            return null;
        }

        ParentEntity parentEntity = new ParentEntity();

        parentEntity.setId( s.getId() );
        parentEntity.setName( s.getName() );
        parentEntity.setChildren( childDtoListToChildEntityList( s.getChildren() ) );

        return parentEntity;
    }

    @Override
    public ParentEntity toEntity(ParentDto s, ParentEntity entity) {
        if ( s == null ) {
            return null;
        }

        entity.setId( s.getId() );
        entity.setName( s.getName() );
        if ( entity.getChildren() != null ) {
            List<ChildEntity> list = childDtoListToChildEntityList( s.getChildren() );
            if ( list != null ) {
                entity.getChildren().clear();
                entity.getChildren().addAll( list );
            }
            else {
                entity.setChildren( null );
            }
        }
        else {
            List<ChildEntity> list = childDtoListToChildEntityList( s.getChildren() );
            if ( list != null ) {
                entity.setChildren( list );
            }
        }

        return entity;
    }

    protected List<ChildDto> childEntityListToChildDtoList(List<ChildEntity> list) {
        if ( list == null ) {
            return null;
        }

        List<ChildDto> list1 = new ArrayList<ChildDto>( list.size() );
        for ( ChildEntity childEntity : list ) {
            list1.add( childMapper.toDto( childEntity ) );
        }

        return list1;
    }

    protected List<ChildEntity> childDtoListToChildEntityList(List<ChildDto> list) {
        if ( list == null ) {
            return null;
        }

        List<ChildEntity> list1 = new ArrayList<ChildEntity>( list.size() );
        for ( ChildDto childDto : list ) {
            list1.add( childMapper.toEntity( childDto ) );
        }

        return list1;
    }
}
@ApplicationScoped
public class ParentMapperImpl implements ParentMapper {

      ...

      @Override
      public ParentEntity toEntity(ParentDto s, ParentEntity entity) {
          if (s == null) {
              return null;
          }

          entity.setId(s.getId());
          entity.setName(s.getName());
          if (entity.getChildren() != null) {
              List<ChildEntity> list = childDtoListToChildEntityList(s.getChildren(), entity.getChildren());
              if (list != null) {
                  entity.getChildren().clear();
                  entity.getChildren().addAll(list);
              } else {
                  entity.setChildren(null);
              }
          } else {
              List<ChildEntity> list = childDtoListToChildEntityList(s.getChildren());
              if (list != null) {
                  entity.setChildren(list);
              }
          }

          return entity;
      }

      ...

      protected List<ChildEntity> childDtoListToChildEntityList(List<ChildDto> list, List<ChildEntity> entities) {
          if (list == null) {
              return null;
          }


          final List<ChildEntity> list1 = new ArrayList<ChildEntity>(list.size());
          for (ChildEntity entity : entities) {
              Optional<ChildEntity> optional = findEntity(entity.getId(), list);
              if (optional.isPresent()) {
                  list1.add(childMapper.toEntity(optional.get(), entity));
              }
          }

          list1.addAll(
                  list.stream()
                          .filter(dto -> dto.getId() == null)
                          .map(dto -> childMapper.toEntity(dto))
                          .collect(Collectors.toList())
          );


          return list1;
      }

      private Optional<ChildEntity> findEntity(Long id, List<ChildDto> list) {
          return list.stream().filter(dto -> dto.getId().equals(id)).findAny();
      }

}          
 类似资料:
  • 我有一种情况,在一个DTO中有另一个DTO,我必须映射到它对应的实体。 我正在使用mapstruct,我已经有antherEntityMapper已经存在。 如何更改EntityMapper接口,以便我可以将一个另一个EntityDTO映射到另一个Entity? 谢谢

  • 我有一个关于mapstruct中@ManyToOne映射的问题。我有两个表 第一个: 第二个是: 我有一个这样的箱子: 和MemberDto作为实体相同。 我需要使用mapstruct进行如下映射: 我需要填写名单成员;但我不明白怎么做。

  • 我正在尝试使用AutoMapper在LLBLGen实体和DTO之间创建映射。 我的DTO如下所示: ParentEntity包含一个与DTO列表同名的ChildCollection和一个Id(需要忽略其他LLBL字段)。因此,当ParentEntity映射到父d to时,它也应该将ChildCollection映射到一个子列表。 这就是我到目前为止得到的: 这会导致Id被映射,但List的计数为0

  • 我不熟悉Mapstruct,在特定用例中遇到问题 因此,如果我的来源属性hotmail.com我的目标属性应该收到“个人”,如果我的来源facebook.com我的目标应该收到“公司”。 我想用表达法,但没法绕过它。我该怎么做?

  • 这是我的例子。 我希望toDto方法使用toDto将Employee映射到EmployeeDto,但mapstruct会生成employeeDtoToEmployeeDto方法。我该怎么修? 谢谢

  • 我希望在我正在从事的一个项目中使用CQR,但是我目前正在努力寻找实现CQR查询端的最佳方法。基于我有限的理解,有一个瘦数据层(有时称为瘦读取层),用于查询数据库并返回DTO,其中包含应用程序UI层使用的查询结果。 由于这是一个Java的EE应用程序,我正在开发薄数据层,使用JPA使用EntityManager.createNamedQuery查询数据库,返回一个包含结果的实体,然后将其映射到DTO