java 如果实体不存在,如何告诉 Springdata-repository 的 delete 方法不抛出异常?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38785622/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 03:46:21  来源:igfitidea点击:

How to I tell a Springdata-repository's delete method to not throw an exception if an entity does not exists?

javaspringspring-data

提问by EhmKah

I am using SpringData's repository. If I try to delete an entity via an ID which does not exist or never existed it throws an exception. Since I do not want to check whether the entity exists before I delete it, it would be nice that it would fail silently. It would make it easier because the observable behavior is the same - after the call the entity does not exists anymore. Whether it has been deleted or never existed, I do not care.

我正在使用 SpringData 的存储库。如果我尝试通过不存在或从未存在的 ID 删除实体,则会引发异常。由于我不想在删除实体之前检查它是否存在,因此它会静默失败会很好。这会更容易,因为可观察的行为是相同的 - 在调用之后实体不再存在。无论它是被删除还是从未存在,我都不在乎。

Is there a way to modify default behavior of delete(EntityId)so it won't throw an exception, if entity does not exsist?

delete(EntityId)如果实体不存在,有没有办法修改的默认行为,所以它不会抛出异常?

Documentation of SpringData's deletesays that it will throw an exception if an entity does not exist.

SpringData 的删除文档说,如果实体不存在,它将抛出异常。

采纳答案by davioooh

Updated Answer (after downvotes)

更新的答案(在downvotes之后)

My original answer (below) is actually wrong: my understanding of the question was influenced also by the missing reference to the EmptyResultDataAccessExceptionin the official JavaDoc (as reported by Adrian Baker in his comment).

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

So a better solution to this issue could be the one suggested by Yamashiro Rion

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

if (repository.existsById(entityId)) {
    repository.deleteById(entityId);
}

or this one (without the if, but probably worse performing):

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

repository.findById(entityId)
    .map(repository::delete)


Original (Wrong) Answer

原始(错误)答案

JavaDocs says that an IllegalArgumentExceptionwill be thrown if the provided argument (id, entity, Iterable<T>) is null and not if entity does not exsits.

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

If you need to avoid the IllegalArgumentExceptionyou could implement a custom delete method that checks id != null:

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

public void customDelete(ID id) {
    if(id != null){
        this.delete(id);
    }
}

Take a look to this docs sectionif you don't know how to add "Custom implementations for Spring Data repositories"

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

回答by Cédric Marion

A viable solution that requires less code is to add a new method to the repository interface like this:

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

// @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);`

--> to be tested if this can used with JPQL instead of native SQL to allow more complex id types than the default ones (int, long, String, ...)

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

回答by Yamashiro Rion

With JpaRepositoryyou can easily delete an entity if it exists. In this example PostsRepositoryextends JpaRepository:

有了JpaRepository你,如果它存在,可以轻松地删除的实体。在这个例子中PostsRepository扩展JpaRepository

if (postsRepository.existsById(postId)) {
    postsRepository.deleteById(postId);
}

回答by Harsha Jayamanna

I used bellow method to throw meaningful exception if the entity was not found.

如果未找到实体,我使用波纹管方法抛出有意义的异常。

if (postsRepository.existsById(postId)) {
    throw new EntityNotFoundExceptionById("Invlaid Id was provided");
}

postsRepository.deleteById(postId);

EntityNotFoundExceptionById Class

EntityNotFoundExceptionById 类

@ResponseStatus(HttpStatus.NOT_FOUND)
public class EntityNotFoundExceptionById extends RuntimeException {

    public EntityNotFoundExceptionById(String message) {
        super(message);
    }

}

回答by Elgayed

Override the method :

覆盖方法:

@Transactional
@Override
    public void delete(ID id) {
        T entity = findOne(id);
        if (entity == null) {
          //do something instead of throwing exception ex:
          //syso entity does not exist ; return;
        }
        em.remove(em.merge(entity));
    }

回答by Вячеслав Калякин

I used @SQLDelete annotation to override default Hibernate DELETE method and to suppress Exception throwing:

我使用@SQLDelete 注释来覆盖默认的 Hibernate DELETE 方法并抑制异常抛出:

@javax.persistence.Entity
@Table(name = "mytable")
@Proxy(lazy = false)
@SQLDelete(
        sql =
        "DELETE FROM mytable " +
        "WHERE my_id = ?"
)
public class MyTable {
  @javax.persistence.Column(name = "my_id", nullable = false)
  @Id
  private Long id;
...
}

then hibernate automatically substitutes the '?' in prepared statement with actual id of MyTable object, which is mapped to SQL field 'my_id' of table

然后休眠会自动替换“?” 在具有 MyTable 对象的实际 id 的准备好的语句中,该对象映射到表的 SQL 字段“my_id”

In this case no exception will be thrown if the record in table does not exist, only silently deletes 0 rows, as in plain SQL DELETE query

在这种情况下,如果表中的记录不存在,则不会抛出异常,只会静默删除 0 行,就像在普通 SQL DELETE 查询中一样