You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Data Rest如何基于父实体@Version实现子实体乐观锁逻辑

你不需要从零自定义@RestController,Spring Data Rest提供了多个轻量扩展点,完全可以在保留原有默认能力(HATEOAS、ALPS、分页、关联资源处理等)的前提下实现子实体修改触发父实体版本递增的需求。


具体实现方案

1. 监听子实体生命周期事件,强制递增父实体版本

Spring Data Rest提供了@RepositoryEventHandler注解,可以监听实体的增删改事件,在操作子实体前对父实体加OPTIMISTIC_FORCE_INCREMENT乐观锁,只要子实体有修改,父实体版本号会自动递增,版本冲突时会直接抛出ObjectOptimisticLockingFailureException,Spring Data Rest会自动转换为409 Conflict响应。
事件监听类代码示例:

import org.springframework.data.rest.core.annotation.HandleBeforeCreate;
import org.springframework.data.rest.core.annotation.HandleBeforeDelete;
import org.springframework.data.rest.core.annotation.HandleBeforeSave;
import org.springframework.data.rest.core.annotation.RepositoryEventHandler;
import org.springframework.stereotype.Component;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import javax.persistence.PersistenceContext;

@Component
@RepositoryEventHandler
public class ChildEntityLifecycleHandler {

    @PersistenceContext
    private EntityManager entityManager;

    // 新增子实体时触发
    @HandleBeforeCreate
    public void beforeCreateChild(Child child) {
        lockParent(child.getParent());
    }

    // 修改子实体时触发
    @HandleBeforeSave
    public void beforeSaveChild(Child child) {
        lockParent(child.getParent());
    }

    // 删除子实体时触发
    @HandleBeforeDelete
    public void beforeDeleteChild(Child child) {
        lockParent(child.getParent());
    }

    private void lockParent(Parent parent) {
        // 对父实体加乐观强制增量锁,修改后自动递增版本,版本不匹配直接抛出锁异常
        entityManager.lock(parent, LockModeType.OPTIMISTIC_FORCE_INCREMENT);
    }
}

2. 适配子实体请求的ETag校验逻辑

因为子实体本身没有@Version字段,默认的ETag生成和校验逻辑不适用,需要做两处适配:

  • 子实体响应的ETag替换为父实体的版本号:可以通过RepresentationModelProcessor自定义返回模型的响应头,或者直接替换ShallowEtagHeaderFilter的ETag生成逻辑,确保客户端拿到的ETag是父实体的版本值。
  • 子实体修改请求的版本校验:通过HandlerInterceptor或者@ControllerAdvice拦截子实体的PUT/PATCH/DELETE请求,拿到请求头If-Match携带的版本值,和关联父实体的当前版本对比,不匹配直接返回409响应即可。

3. 父实体自身修改的兼容

父实体本身自带@Version注解,原有默认的ETag校验和版本递增逻辑不需要做任何修改,会正常生效。

以上改造完成后,原有@RepositoryRestResource暴露的所有接口能力完全保留,不需要额外开发HATEOAS、ALPS相关逻辑。


内容的提问来源于stack exchange,提问作者Meini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 01:30:00