如何防止使用spring数据rest保存现有实体

vsaztqbk  于 2021-07-16  发布在  Java
关注(0)|答案(2)|浏览(360)

(Kotlin样品)
我有一个具有手动分配ID的实体:

@Entity
@Table(name = "Item")
class Item {
  @Id
  @Column(name = "ItemId", nullable = false, updatable = false)
  var id: Int? = null

  @Column(name = "Name", nullable = false)
  var name: String? = null
}

以及spring数据rest存储库:

interface ItemRepository : PagingAndSortingRepository<Item, Int>

如果我做一个 POST/items 使用现有id,将覆盖现有对象。我希望它会抛出一个错误。有没有一种方法可以配置这种行为,而不必为每种资源类型滚动我自己的save方法?
谢谢。

6bc51xsx

6bc51xsx1#

在本文的帮助下,我最终使用了一个spring验证器。
我创建了如下验证程序:

class BeforeCreateItemValidator(private val itemRepository: ItemRepository) : Validator {
    override fun supports(clazz: Class<*>) = Item::class.java == clazz

    override fun validate(target: Any, errors: Errors) {
        if (target is Item) {
            itemRepository
                .findById(target.id!!)
                .ifPresent {
                    errors.rejectValue("id",
                                       "item.exists",
                                       arrayOf(target.id.toString()),
                                       "no default message")
                }
        }
    }
}

然后使用以下配置进行设置:

@Configuration
class RestRepositoryConfiguration(
        private val beforeCreateItemValidator: BeforeCreateItemValidator
    ) : RepositoryRestConfigurer {

    override fun configureValidatingRepositoryEventListener(
        validatingListener: ValidatingRepositoryEventListener) {
        validatingListener.addValidator("beforeCreate", beforeCreateItemValidator)
    }
}

这样做会导致服务器返回 400 Bad Request (我更希望能换成 409 Conflict ,但是 400 可以)以及带有 errors 包含自定义消息的属性。这对于我检查一个实体来说是很好的,但是如果我的整个应用程序都手动分配了id,那么这样做可能会有点混乱。我想看到一个springdatarest配置选项,它只禁用覆盖。

nnsrf1az

nnsrf1az2#

可以向用注解的实体添加版本属性 @Version 这将启用乐观锁定。如果始终为版本0提供新实体,则当该实体已存在(具有不同版本)时,应该会出现异常。
当然,您还需要为更新提供该版本。

相关问题