如果实体不存在,如何告诉Springdata存储库的delete方法不引发异常?

Ehm*_*Kah 8 java spring spring-data

我正在使用SpringData的存储库。如果我尝试通过不存在或不存在的ID删除实体,则会引发异常。由于我不想在删除该实体之前检查该实体是否存在,因此很高兴它会静默失败。因为可以观察到的行为是相同的,所以它将变得更加容易-调用之后,实体不再存在。它是否已删除还是从不存在,我不在乎。

delete(EntityId)如果实体不存在,是否有办法修改默认行为,以便不会引发异常?

SpringData的删除文档表明,如果实体不存在,它将引发异常。

dav*_*ooh 19

更新的答案(在downvotes之后)

我的原始答案(如下)实际上是错误的:我对这个问题的理解也受到EmptyResultDataAccessException官方 JavaDoc 中缺少引用的影响(正如 Adrian Baker 在他的评论中所报告的那样)。

所以这个问题的更好解决方案可能是 Yamashiro Rion 建议的

if (repository.existsById(entityId)) {
    repository.deleteById(entityId);
}
Run Code Online (Sandbox Code Playgroud)

或者这个(没有if,但可能表现更差):

repository.findById(entityId)
    .map(repository::delete)
Run Code Online (Sandbox Code Playgroud)

原始(错误)答案

JavaDocs 表示,IllegalArgumentException如果提供的参数 (id, entity, Iterable<T>) 为 null 而不是如果 entity 不存在,则抛出an 。

如果你需要避免IllegalArgumentException你可以实现一个自定义的删除方法来检查id != null

public void customDelete(ID id) {
    if(id != null){
        this.delete(id);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您不知道如何添加“Spring Data 存储库的自定义实现”,请查看此文档部分

  • 我看不出这个答案如何针对不存在的实体的问题?提供的 ID 参数可能是非空的,但数据存储中不存在这样的实体。在这种情况下,此答案如何防止出现异常? (5认同)
  • 尽管很遗憾没有在 javadoc 中说明,如果实体不存在, org.springframework.data.jpa.repository.support.SimpleJpaRepository 实现会抛出 EmptyResultDataAccessException 。 (4认同)

Art*_*tem 12

在您的存储库中,您应定义返回类型的方法Integer

Integer deleteMyEntityById(Long id);
Run Code Online (Sandbox Code Playgroud)

如果要删除的实体不存在,并且该实体已被删除,则您的方法将返回 0 或 1。


wkg*_*ass 7

非常简单的解决方案:添加All到方法名称。

使用void deleteAllById(ID id)而不是delete(ID) or deleteById(ID).

这个方法应该是你自己定义的,它不是来自spring内置的CRUDRepository

这个方案是可行的,但是这是否符合spring data规范,看评论自行判断。

  • 这是行不通的。而 `deleteAllById` 方法需要一个列表 (3认同)

小智 5

一个需要较少代码的可行解决方案是向存储库接口添加一个新方法,如下所示:

// @Modifying is necessary depending on your version of Spring
@Modifying
@Query(nativeQuery=true, value="DELETE FROM MY_TABLE WHERE ID = ?1")
public void deleteById(IdPrimitiveType id);`
Run Code Online (Sandbox Code Playgroud)

->测试是否可以将其与JPQL而不是本机SQL一起使用,以允许比默认ID类型更复杂的ID类型(int,long,String等)

  • 看起来这是唯一有效的答案,其余的都有竞争条件 (3认同)
  • 无需将其设为原生查询,JPQL 即可进行批量删除。 (2认同)