Как обновить указанный объект с помощью запроса PATCH в Spring data-rest - PullRequest
0 голосов
/ 18 июня 2020

У меня есть 2 связанных объекта: Project и System. Сопоставление выглядит так в классе Project:

@ManyToOne
@JoinColumn(name = "system_id")
@NotNull
private System system;

Я пытаюсь использовать Spring data-rest для реализации API basi c rest для проектов. Простые вещи, такие как GET или обновление простых свойств, отлично работают. Но этот запрос вызывает трудности:

PATCH /api/projects/1 HTTP/1.1
{
  "name": "Name2",
  "system": {
    "id": 1
  }
}

Я хочу, чтобы этот запрос изменил имя и связанный системный объект, и не могу найти способ, как это сделать. Я понимаю, что есть возможность обновить ссылки с помощью дополнительного запроса, как описано здесь: https://www.baeldung.com/spring-data-rest-relationships. Но мне нужно сохранить устаревший интерфейс API, поэтому мне нужно заставить этот интерфейс работать. Выдается следующая ошибка:

Caused by: org.hibernate.HibernateException: identifier of an instance of com.company.resourceapi.entities.Project was altered from 3 to 1

Upd. Чтобы уточнить: до обновления Project

id: 1,
name: "Name1",
system_id: 2

после запроса PATCH я хочу увидеть

id: 1,
name: "Name2",
system_id: 1

1 Ответ

0 голосов
/ 18 июня 2020

Я придумал это не очень элегантное решение: я переопределяю метод save в репозитории следующим образом:

public class ProjectRepositoryImpl implements CustomSaveRepo<Project> {
    @Autowired
    private SystemRepository repository;
    @Autowired
    private EntityManager em;

    @Transactional
    @Override
    public Project save(Project entity) {
        // entity.system has the id from the request, in the same time it's managed entity.
        if (entity.getSystem() != null) {
            Long sysId = entity.getSystem().getId();
            if (sysId != null) {
                em.detach(entity.getSystem());
                System system = repository.findById(sysId)
                        .orElseThrow(() -> new RuntimeException());
                entity.setSystem(system );
            }
        }
        entity.setUpdatedAt(new Date());

        em.persist(entity);

        return entity;
    }
}

Был бы признателен, если бы кто-нибудь поделился со мной лучшим решением.

...