我在我的Spring Boot应用程序中使用spring-data-rest
,我注意到POST请求中有一种奇怪的行为。
如果我使用包含id值的正文向我的http://<basepath>/<repository>
端点发出POST请求,则Spring会尝试使用该ID值更新记录。但是,如果该记录的版本字段不为零,则此类POST请求将返回错误
Object of class [com.foo.bar.schema.entity] with identifier [c6aba26a-79a9-34e4-a520-b447e446c2bd]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [com.foo.bar.schema.entity#c6aba26a-79a9-34e4-a520-b447e446c2bd]
获得这个错误的解决方案会很好,但我宁愿没有人通过传递记录的标识符来通过POST请求更新记录。我有PUT / PATCH。
有什么方法可以做到这一点吗?
我找到了解决这个问题的方法。我正在使用自定义PermissionEvaluator
我在自动装配HttpServletRequest
然后在hasPermission
方法我检查是否request.getMethod()
是POST并且实体没有ID。
@Component
public class CustomPermissionEvaluator implements PermissionEvaluator {
private HttpServletRequest request;
@Autowired
public CustomPermissionEvaluator(HttpServletRequest request) {
this.request = request;
}
@Override
public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
if (targetDomainObject instanceof TableEntity) {
TableEntity entity = (TableEntity) targetDomainObject;
if (HttpMethod.resolve(request.getMethod()) == HttpMethod.POST && entity.getId() != null) {
return false;
}
}
return true;
}
}