Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Преобразование DTO в сущность для обновления Java: Корпоративные приложения на Spring Boot

Создание и обновление сущности — это похожие операции, но все таки они совпадают не полностью. Различия между операциями приводят к тому, что нам нужно создавать свои DTO под каждую из них. В этом уроке мы научимся реализовывать операцию обновления с учетом DTO.

Возьмем для примера Post. Как правило, слаг в постах не меняется после создания. Если его изменить, все ссылки на пост перестанут работать и начнут выдавать ошибку 404. Технически это означает, что для обновления мы должны запретить изменять слаг. Фактически нам придется создать свой DTO для операции обновления.

В итоге мы сделаем три DTO для CRUD всего одной сущности. Может показаться, что это слишком много. К сожалению, здесь нет идеального решения. Свой DTO под каждый тип операции — это самое простое и устойчивое к ошибкам решение, хотя оно и приводит к большему объему кода.

Посмотрим, как выглядит наш DTO для создания сущности:

package io.hexlet.spring.dto;

import lombok.Getter;
import lombok.Setter;

@Setter
@Getter
public class PostCreateDTO {
    private String slug;
    private String name;
    private String body;
}

В таком случае DTO для обновления будет выглядеть так:

package io.hexlet.spring.dto;

import lombok.Getter;
import lombok.Setter;

@Setter
@Getter
public class PostUpdateDTO {
    private String name;
    private String body;
}

Второе отличие обновления от создания связано с тем, что мы не создаем новый объект, а меняем уже существующий. То есть правильная реализация обновления выглядит так:

var post = postRepository.findById(id);
post.setName(dto.getName());
// остальной код
postRepository.save(post); // UPDATE

Учитывая все сказанное выше, мы получим следующий обработчик в контроллере:

@RestController
@RequestMapping("/api")
public class PostsController {
    @Autowired
    private PostRepository repository;

    @PutMapping("/posts/{id}")
    @ResponseStatus(HttpStatus.OK)
    public PostDTO update(@RequestBody @Valid PostUpdateDTO postData, @PathVariable Long id) {
        var post = repository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("Not Found"));
        toEntity(postData, post);
        repository.save(post);
        var postDTO = toDTO(post);
        return postDTO;
    }

    private Post toEntity(PostUpdateDTO postDto, Post post) {
        post.setName(postDto.getName());
        post.setBody(postDto.getBody());
        return post;
    }

    private PostDTO toDTO(Post post) {
        var dto = new PostDTO();
        dto.setId(post.getId());
        dto.setSlug(post.getSlug());
        dto.setName(post.getName());
        dto.setBody(post.getBody());
        dto.setCreatedAt(post.getCreatedAt());
        return dto;
    }
}

У этой реализации есть одно важное ограничение — она не поддерживает частичное обновление. Для примера представим, что мы передали ей новое значение и не уточнили, что хотим оставить старое. В таком случае эта реализация просто удалит старое значение. В одном из следующих уроков мы обсудим, как решить эту проблему.


Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
от 6 300 ₽ в месяц
Разработка приложений на языке Java
10 месяцев
с нуля
Старт 2 мая

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»
Изображение Тото

Задавайте вопросы, если хотите обсудить теорию или упражнения. Команда поддержки Хекслета и опытные участники сообщества помогут найти ответы и решить задачу