首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ModelMapper DTO到实体

ModelMapper DTO到实体
EN

Stack Overflow用户
提问于 2021-11-12 05:46:17
回答 1查看 1.7K关注 0票数 0

我正在为我的班级做一个项目。需要将DTO映射到实体,反之亦然。我的DTO没有Id字段,转换正在控制器层进行。其他两个类正在扩展我的实体,因此@Superbuilder。

我的转换实体 -> DTOModelMapper一起工作很好

DTO -> Entity没有。我认为convertToEntity中的注释行应该可以工作,但是nope一直得到臭名昭著的“有非私有的无参数构造函数”。花了好几个小时来修复。决定使用一种更简单的解决方案,尽管它确实想让ModelMapper工作。

如果你们谁能帮我找到解决办法,我会很感激的。提前感谢您的时间和回应。

======My DTO=====

代码语言:javascript
复制
@Value
@Jacksonized
@Builder
@AllArgsConstructor
public class UserMetaData {

    @NotNull @NotBlank @NotEmpty(message = "First name cannot be empty!")
    @JsonProperty("firstName")
    String firstName;
    @NotNull @NotBlank @NotEmpty(message = "Last name cannot be empty!")
    @JsonProperty("lastName")
    String lastName;
    @Max(value = 110, message = "Invalid age!") @Min(value = 16, message = "Must be older than 16!")
    @JsonProperty("age")
    int age;
    @NotNull
    @JsonProperty("privilege")
    Privilege privilege;
    //@NotNull
    @JsonProperty("alias")
    String alias;
    //@Singular
    @JsonProperty("groups")
    Set<Group> groups;


}

=====My Entity=====

代码语言:javascript
复制
@Document(collection = "Users")
@SuperBuilder
@Data
@RequiredArgsConstructor(onConstructor = @__(@PersistenceConstructor))
public class Member implements User {

@Id
protected final UUID id;
protected final String firstName;
protected final String lastName;
protected final int age;
@Builder.Default
protected final Privilege privilege = NONE;
protected String alias;
protected Set<Group> groups;

protected Set<Group> addGroup(Group group) {
    this.groups.add(group);
    return this.groups;
}

}

=====Bean for ModelMapper=====

代码语言:javascript
复制
 @Bean
public ModelMapper modelMapper() {
    ModelMapper modelMapper = new ModelMapper();
    modelMapper.getConfiguration()
            .setFieldMatchingEnabled(true)
            .setFieldAccessLevel(org.modelmapper.config.Configuration.AccessLevel.PRIVATE);
    return modelMapper;
}

=====Converters=====

代码语言:javascript
复制
 private UserMetaData convertToDTO(Member member) {
    return modelMapper.map(member, UserMetaData.UserMetaDataBuilder.class)
            .build();
}

private Member convertToEntity(UserMetaData dto) {
//        return modelMapper.map(dto, Member.MemberBuilder.class).id(UUID.randomUUID()).build();
    return Member.builder()
            .id(UUID.randomUUID())
            .firstName(dto.getFirstName())
            .lastName(dto.getLastName())
            .age(dto.getAge())
            .build();
}
EN

回答 1

Stack Overflow用户

发布于 2021-11-12 08:16:24

DTO类使用@Builder,而Entity类使用@SuperBuilder

@Builder@SuperBuilder存在差异。编译项目后查看target文件:

  • @Builder将创建一个名为DTOBuilder的静态类,并且它有一个公共构造函数

代码语言:javascript
复制
public class DTO {
    //...
    public static class DTOBuilder {
         public DTOBuilder() {
         }
    }
}

  • @SuperBuilder将创建一个带有private constructor

public abstract class EntityBuilderprivate implemented class EntityBuilderImpl

代码语言:javascript
复制
public class Entity {
     //...
     public abstract static class EntityBuilder<...> {
     }
     //...
     private static final class EntityBuilderImpl extends EntityBuilder {
            private EntityBuilderImpl() {
            }
     }
}

因此,ModelMapper要求目标类应该是public classpublic contructor。这就是为什么您不能映射到EntityBuilder,但是DTOBuilder没有问题。

解决方案不是映射到EntityBuilder,而是应该直接映射到实体。注意,您的实体必须有No Args Constructor

@NoArgsConstructor添加到实体中,并将DTO转换为实体类而不是EntityBuilder

代码语言:javascript
复制
//...
@NoArgsConstructor
public class Member implements User {
//...
}

private Member convertToEntity(UserMetaData dto) {
    return modelMapper.map(dto, Member.class);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69938452

复制
相关文章

相似问题

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