【问题标题】:ModelMapper & JPA: How to map DTO with id to Entity with oneToMany fieldModelMapper & JPA:如何将带有 id 的 DTO 映射到带有 oneToMany 字段的实体
【发布时间】:2022-07-14 15:30:31
【问题描述】:

ModelMapper 在将我的实体转换为 DTO 方面一直表现出色,但我无法反过来,因为我的大多数实体至少有一个字段是另一个实体本身。

组:

@Entity
@Table(name = "GROUPS_")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Group {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    private Long id;

    @Column(name = "NAME", nullable = false)
    private String name;

    @ManyToOne
    @JoinColumn(name = "AREA_ID", nullable = false)
    private Area area;
}

地区:

@Entity
@Table(name = "AREAS")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Area {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    private Long id;

    @Column(name = "NAME", nullable = false)
    private String name;
}

GroupDTO:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class GroupRequestDTO {
    private String name;
    private Long areaId;
}

我想做什么:

private Group mapToEntity (GroupRequestDTO groupRequestDTO){
    return modelMapper.map(Group.class,groupRequestDTO);
}

我期望的行为(也是我当前的实现)

private Group mapToEntity (GroupREquestDTO groupRequestDTO){
    return new Group(
        null,
        groupRequestDTO.getName(),
        entityManager.getReference(Area.class, groupRequestDTO.getAreaId())
    )
}

知道我的 RequestDTO 将始终具有名称为 [entitiy]Id 的引用实体 id 并且所有实体的 id 都称为“id”可能会很有用

额外的问题,有没有办法为我的其他实体概括这一点?我可以为每个实体设置自定义映射(没有那么多),但如果 modelMapper 知道将“fooId”转换为 Foo 实体/引用,那就太好了

【问题讨论】:

    标签: java spring jpa spring-data-jpa modelmapper


    【解决方案1】:

    我也遇到了同样的问题,这就是我如何将我的 DTO 与 Id 列表映射到实体列表(即 @ManyToMany)或将 Id 映射到具有 @ManyToOne 的实体。

    首先,将构造函数添加到您的区域或子实体,如下所示:

    @Entity
    @Table(name = "AREAS")
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Area {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "ID")
        private Long id;
    
        @Column(name = "NAME", nullable = false)
        private String name;
    
        public Area(Long id) {
            this.id = id;
        }
    }
    

    然后在您的控制器层或您的测试类中,您必须按如下方式制作转换器

        private final ModelMapper mapper = new ModelMapper();
        Converter<Long, Area> idToArea = ctx -> new Area(ctx.getSource());
    

    接下来在你的方法中你可以这样做:

    @Test
    public void testMapDTOToEntity() {
        GroupRequestDTO groupRequestDTO = new GroupRequestDTO("Europe",12L);
        TypeMap<GroupRequestDTO, Group> propertyMapper = 
        this.mapper.createTypeMap(GroupRequestDTO.class, Group.class);
        propertyMapper.addMappings(mapper -> {
            mapper.using(idToArea).map(GroupRequestDTO::getAreaId, Group::setArea);
        });
    
        Group group = mapper.map(groupRequestDTO,Group.class);
        Assertions.assertEquals(group.getName(), groupRequestDTO.getName());
        Assertions.assertEquals(group.getArea().getId(), 
        groupRequestDTO.getAreaId());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-25
      • 2012-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多