【问题标题】:How to prevent saving over an existing entity with Spring Data REST如何使用 Spring Data REST 防止保存现有实体
【发布时间】:2021-06-16 02:13:06
【问题描述】:

(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 Data REST 存储库:

interface ItemRepository : PagingAndSortingRepository<Item, Int>

如果我使用现有 ID 对/items 执行POST,则现有对象将被覆盖。我希望它会抛出一个错误。有没有办法在不为每种资源类型滚动我自己的保存方法的情况下配置该行为?

谢谢。

【问题讨论】:

    标签: spring spring-data-jpa spring-data-rest


    【解决方案1】:

    this article 的帮助下,我最终使用了Spring Validator

    我这样创建了验证器:

    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 属性的JSON 正文,其中包含我的自定义消息。这对于我检查一个实体的目的来说很好,但是如果我的整个应用程序都手动分配了 ID,那么这样做可能会有点混乱。我希望看到一个 Spring Data REST 配置选项来禁用覆盖。

    【讨论】:

      【解决方案2】:

      您可以为带有@Version 注释的实体添加版本属性,这将启用乐观锁定。如果您始终为版本 0 提供新实体,那么当该实体已经存在(具有不同版本)时,您应该会收到异常。

      当然,您还需要提供该版本以进行更新。

      【讨论】:

      • 在我有机会尝试之前找到了自己的(不同的)解决方案。谢谢!
      猜你喜欢
      • 2019-09-30
      • 1970-01-01
      • 2013-05-09
      • 1970-01-01
      • 2020-04-22
      • 2014-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多