为什么Spring Data(JPA)的删除方法没有任何返回值?

14

我在服务层使用了Spring Data JPA的删除方法,但是我想知道为什么deleteById方法和delete方法都没有返回值。

如果我们仔细检查删除方法的实现,会发现有一个if语句,当要删除的实体不存在时,它不会返回任何内容。

public void delete(T entity) {

    Assert.notNull(entity, "Entity must not be null!");

    if (entityInformation.isNew(entity)) {
        return;
    }

    Class<?> type = ProxyUtils.getUserClass(entity);

    T existing = (T) em.find(type, entityInformation.getId(entity));

    // if the entity to be deleted doesn't exist, delete is a NOOP
    if (existing == null) {
        return;
    }

    em.remove(em.contains(entity) ? entity : em.merge(entity));
}

我个人认为,在这种情况下返回布尔值可能是一种足够的方法,因为控制器层将了解删除状态,视图层可以提供更可靠的警告消息。


如果在“delete”期间没有抛出异常,那么一切都正常。请记住,您正在操作JPQL而不是SQL。您期望什么可靠的信息? - Nikolai Shevchenko
因为JPA既不返回布尔值也不返回空值... - xerx593
对于这个信息(在 jpa 中),你需要使用 Query.executeUpdate():int,并捕获异常:) 这将可靠地返回修改/更新/删除行的计数。 - xerx593
...而且 Spring Data 也可以。https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.modifying-queries.derived-delete(Abinash的回答) - xerx593
3个回答

18

Spring Data JPA 设计了一些内置方法,它们提供了一种方式,并让我们有选择地使用其他方式。您可以使用 Spring Data JPA 支持的派生删除查询轻松获取已删除记录及其计数 (参考文献)。

@Repository
public interface FruitRepository extends JpaRepository<Fruit, Long> {
    Fruit deleteById(Long id); // To get deleted record
}
@Repository
public interface FruitRepository extends JpaRepository<Fruit, Long> {
    Long deleteById(Long id);  // To get deleted record count
}

你的意思是我只需要在repository中放置Fruit deleteById(Integer id);,Spring Data JPA就会自动完成其余操作并返回被删除的记录吗?我使用了上述代码,在repository中删除了请求的实体条目,但它返回的是null(而不是已删除的记录!),尽管没有抛出任何异常。 - Elyas Hadizadeh
@ElyasHadizadeh 是的。官方文档:核心概念->示例6 https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.core-concepts - Eklavya
6
返回类型与 CrudRepository<TestoEntity, Long>.deleteById(Long) 不兼容:无法工作。 - Phate
嗨,我看不到更新,有什么方法可以完成这个吗? - Phate
@dpelisek 我的意图是展示两种方法,我并不是说你可以在同一个代码库中同时使用这两种方法。我已经更新了我的回答来澄清这一点。 - Eklavya

5

使用 @Modifying@Query,它将返回已删除的行数。

@Repository
public interface FruitRepository extends JpaRepository<Fruit, Long> {
    @Modifying
    @Query(value = "DELETE FROM Fruit f where f.id = ?1")
    int costumDeleteById(Long id);
}

0

另一个选择是遵循这个答案的建议,并检查受影响实体的数量是否为1(在deleteById方法的情况下)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接