首页 > 解决方案 > 如何在 spring data-rest 中使用 PATCH 请求更新引用的对象

问题描述

我有 2 个连接的实体:项目和系统。映射在 Project 类中如下所示:

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

我正在尝试使用 spring data-rest 来实现项目的基本 rest API。像 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

更新。澄清:在更新之前,项目是

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

在 PATCH 请求后我想看看

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

标签: javaspringspring-data-rest

解决方案


I came up with this not very elegant solution: I override save method in repository like that:

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;
    }
}

Would be grateful is someone shared with me a better solution.


推荐阅读