如何使用Java记录作为ModelMapper的DTO?
我正在重构我的代码。我想在DTO中使用java记录而不是java类。要将DTO转换为实体,我使用ModelMapper(版本2.3.5)。当我试图获取有关用户的信息(调用方法将实体转换为DTO)时,我得到了这个错误
Failed to instantiate instance of destination xxx.UserDto. Ensure that xxx.UserDto has a non-private no-argument constructor.
这是我的密码
public record UserDto(String firstName,
String lastName,
String email,
String imageUrl) {}
@RestController
public class UserController {
@Autowired
private UserRepository userRepository;
@Autowired
private ModelMapper modelMapper;
@GetMapping("/user/me")
@PreAuthorize("hasRole('USER')")
public UserDto getCurrentUser(@CurrentUser UserPrincipal userPrincipal) {
return convertToDto(userRepository.findById(userPrincipal.getId())
.orElseThrow(() -> new ResourceNotFoundException("User", "id", userPrincipal.getId())));
}
private UserDto convertToDto(User user) {
UserDto userDto = modelMapper.map(user, UserDto.class);
return userDto;
}
private User convertToEntity(UserDto userDto) throws Exception {
User post = modelMapper.map(userDto, User.class);
return post;
}
}
编辑:更新到版本2.3.8
没有帮助
# 1 楼答案
record
是Java14中的预览功能,因此我建议您不要在生产环境中使用它。其次,它没有模仿JavaBeanrecord
没有默认的无参数构造函数(如果有字段)。如果编写了无参数构造函数,则必须将调用委托给所有参数构造函数,因为所有字段都是final
,所以只能设置一次。所以你被困在那里了。见JEP 359:今天起作用的另一种选择是使用^{} 。使用Lombok的
UserDto
示例:# 2 楼答案
记录的字段是最终字段,因此必须通过构造函数进行设置。不管怎样,许多框架都会欺骗并使用各种技巧在事后修改最终字段,但这些技巧对记录不起作用。如果要实例化记录,必须在构造时提供所有字段值
框架了解记录可能需要一点时间。“调用无参数构造函数,然后设置字段”的旧模型对记录不起作用。一些框架已经能够处理这个问题(例如,“构造函数注入”),而其他框架还没有。但是,我们预计框架很快就会实现
正如评论者所说,您应该鼓励您的框架提供商支持它们。这并不难