有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

如何使用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没有帮助


共 (2) 个答案

  1. # 1 楼答案

    record是Java14中的预览功能,因此我建议您不要在生产环境中使用它。其次,它没有模仿JavaBean

    record没有默认的无参数构造函数(如果有字段)。如果编写了无参数构造函数,则必须将调用委托给所有参数构造函数,因为所有字段都是final,所以只能设置一次。所以你被困在那里了。见JEP 359

    It is not a goal to declare "war on boilerplate"; in particular, it is not a goal to address the problems of mutable classes using the JavaBean naming conventions.

    今天起作用的另一种选择是使用^{}。使用Lombok的UserDto示例:

    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    public class UserDto {
        private String firstName;
        private String lastName;
        private String email;
        private String imageUrl;
    }
    
  2. # 2 楼答案

    记录的字段是最终字段,因此必须通过构造函数进行设置。不管怎样,许多框架都会欺骗并使用各种技巧在事后修改最终字段,但这些技巧对记录不起作用。如果要实例化记录,必须在构造时提供所有字段值

    框架了解记录可能需要一点时间。“调用无参数构造函数,然后设置字段”的旧模型对记录不起作用。一些框架已经能够处理这个问题(例如,“构造函数注入”),而其他框架还没有。但是,我们预计框架很快就会实现

    正如评论者所说,您应该鼓励您的框架提供商支持它们。这并不难