java - ModelMapper DTO 到实体
问题描述
我正在为我的班级做一个项目。需要将DTO映射到实体,反之亦然。我的DTO没有Id字段,并且转换发生在Controller Layer。其他 2 个类正在扩展我的实体,因此是 @Superbuilder。
我的转换实体- > DTO与ModelMapper配合得很好
但是DTO -> Entity没有。我认为convertToEntity中的注释行应该可以工作,但是没有得到臭名昭著的 ' has non-private no-argument constructor '。花了几个小时试图修复。决定采用更简单的解决方案,尽管真的想让ModelMapper工作。
如果你们中的任何人可以帮助我找到解决方法,我将不胜感激。提前感谢您的时间和回复。
======我的 DTO=====
@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;
}
=====我的实体=====
@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;
}
}
=====ModelMapper 的 Bean=====
@Bean
public ModelMapper modelMapper() {
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration()
.setFieldMatchingEnabled(true)
.setFieldAccessLevel(org.modelmapper.config.Configuration.AccessLevel.PRIVATE);
return modelMapper;
}
=====转换器=====
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();
}
解决方案
您的DTO
班级正在使用@Builder
,而您的Entity
班级正在使用@SuperBuilder
. 和
之间有区别。编译项目后查看文件:@Builder
@SuperBuilder
target
@Builder
将创建一个名为的静态类DTOBuilder
,它有一个公共构造函数
public class DTO {
//...
public static class DTOBuilder {
public DTOBuilder() {
}
}
}
@SuperBuilder
将创建 apublic abstract class EntityBuilder
和 aprivate implemented class EntityBuilderImpl
与 aprivate constructor
public class Entity {
//...
public abstract static class EntityBuilder<...> {
}
//...
private static final class EntityBuilderImpl extends EntityBuilder {
private EntityBuilderImpl() {
}
}
}
所以,ModelMapper
要求目标类应该是public class
and public contructor
。这就是为什么您无法映射到EntityBuilder
但可以使用DTOBuilder
.
解决方案是,EntityBuilder
您应该直接映射到实体,而不是映射到。请注意,您的实体必须具有No Args Constructor
添加@NoArgsConstructor
到您的 Entity 并从您的 DTO 转换为 Entity 类而不是 EntityBuilder
//...
@NoArgsConstructor
public class Member implements User {
//...
}
private Member convertToEntity(UserMetaData dto) {
return modelMapper.map(dto, Member.class);
}
推荐阅读
- laravel - laravel 收银员 webhook 在生产中,如何跟上听众?
- pip - 为什么在安装 rasa 时出现 h5py 错误?
- image - 我正在尝试在网格中并排获取 img 和 text 。我不工作
- mysql - SQL使用本地表的值到不同数据库中的引用表
- java - 未找到文件异常:(文件存在)-手动删除后
- audio - ffmpeg HLS 多尺寸,没有音频
- java - 如何在 Java 中访问 BasicDynaBean 类型的对象的元素?
- asp.net - @Html.DisplayFor(ModelItem => item.Category.Name) 不显示类别名称
- php - 如何在我的 PHP MySQL 查询中修复此语法错误
- java - java.lang.NoClassDefFoundError:解析失败:Ljava/sql/DriverAction;