Olá Artur.
Tudo bem?
Realmente, a imutabilidade dos DTOs é uma prática recomendada para garantir a segurança e a consistência dos dados. No entanto, quando se trata de receber dados via Multipart, o Spring MVC espera que os objetos sejam mutáveis para que ele possa injetar os valores corretamente.
Para resolver isso, você pode usar uma abordagem alternativa que mantém a imutabilidade dos seus DTOs. Uma solução é criar uma classe intermediária que seja mutável e depois converter essa classe em um DTO imutável. Aqui está um exemplo de como você pode fazer isso:
- Crie uma classe intermediária mutável:
 
public class HotelForm {
    private String nome;
    private String endereco;
    private MultipartFile imagem;
    // Getters e Setters
    public String getNome() {
        return nome;
    }
    public void setNome(String nome) {
        this.nome = nome;
    }
    public String getEndereco() {
        return endereco;
    }
    public void setEndereco(String endereco) {
        this.endereco = endereco;
    }
    public MultipartFile getImagem() {
        return imagem;
    }
    public void setImagem(MultipartFile imagem) {
        this.imagem = imagem;
    }
}
- Crie seu DTO imutável:
 
public class HotelDto {
    private final String nome;
    private final String endereco;
    private final byte[] imagem;
    public HotelDto(String nome, String endereco, byte[] imagem) {
        this.nome = nome;
        this.endereco = endereco;
        this.imagem = imagem;
    }
    // Getters
    public String getNome() {
        return nome;
    }
    public String getEndereco() {
        return endereco;
    }
    public byte[] getImagem() {
        return imagem;
    }
}
- Converta a classe intermediária para o DTO no seu controlador:
 
@PutMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE, value = "/updateHotel")
public ResponseEntity<HotelDto> updateHotel(@ModelAttribute @Valid HotelForm form) {
    byte[] imagemBytes = null;
    try {
        imagemBytes = form.getImagem().getBytes();
    } catch (IOException e) {
        // Trate a exceção adequadamente
        e.printStackTrace();
    }
    HotelDto dto = new HotelDto(form.getNome(), form.getEndereco(), imagemBytes);
    // Chame o serviço para atualizar o hotel com o DTO
    service.updateHotel(dto);
    return ResponseEntity.ok(dto);
}
Dessa forma, você mantém a imutabilidade dos seus DTOs enquanto ainda permite que o Spring MVC injete os valores via Multipart.
Veja se isso te ajuda, se faz sentido. Qualquer dúvida manda aqui.
Espero ter ajudado e bons estudos!