Spring Data Jpa 在Spring Repository接口中使用delete和deleteById的好处

laximzn5  于 2023-06-06  发布在  Spring
关注(0)|答案(1)|浏览(206)

我真的很想知道为什么在Spring CrudRepository接口中有一个void deleteById(ID id);和一个void delete(T entity);
在我的代码中,我使用的是JpaRepository,它扩展了CrudRepository。在这种情况下,Spring中的具体实现是SimpleJpaRepository。如果你看一下这个类,你可以看到,在引擎盖下,deleteById(ID id)首先调用findById(id),然后调用delete(T entity)
看起来如果我使用delete(T entity),对象的内容就不重要了。我尝试了以下操作:

@Test
void deleteEntry() {
    Product product = new Product();
    product.setSku("ABCDE");
    product.setName("name");
    product.setDescription("description");
    product.setPrice(BigDecimal.valueOf(42l));
    product.setActive(true);
    product.setImageUrl("imageUrl");

    productRepository.save(product);
    
    // new product, only ID is set, all other fiels are empty
    Product product1Delete = new Product();
    product1Delete.setId(product.getId());

    // use the mostly empty enitity to delete the "product" entity saved before
    productRepository.delete(product1Delete);
    
    // as the database for the entity which the deleted ID
    Optional<Product> productGivenFromDb = productRepository.findById(product.getId());

    // entity isn't present in the database anymore
    Assertions.assertTrue(!productGivenFromDb.isPresent());
}

而且,正如预期的那样,在查看了SimpleJpaRepository之后,它正在工作。给定实体的内容除了ID之外完全被忽略。

  • 现在我的问题是:* 我只是不明白为什么有两个删除方法。为什么我们没有deleteById(ID id);?如果没有看一下实现,我会期望整个实体被用来找到应该被删除的那个实体,但是,正如你所看到的,除了ID之外的所有东西都被忽略了。因此,在本例中,两个函数的作用完全相同,我无法想象有任何用例需要删除实体,但没有ID。

或者有没有其他的实现,以不同的方式处理这两个?有什么历史原因让两者都有?还是方便的原因?
有人能指点我一下吗?我真的很感激!

vmjh9lq9

vmjh9lq91#

如果您查看这两个方法的实现,deleteById本身使用delete。例如,如果请求只向服务器传递id,我们使用deleteById(它使用findById和delete),但如果代码中有实体,我们使用delete,不再需要deleteById。
SimpleJpaRepository:

@Transactional
    @Override
    public void deleteById(ID id) {

        Assert.notNull(id, ID_MUST_NOT_BE_NULL);

*****It uses findById and delete(T entity)*****

        delete(findById(id).orElseThrow(() -> new EmptyResultDataAccessException(
                String.format("No %s entity with id %s exists!", entityInformation.getJavaType(), id), 1)));
    }

    /*
     * (non-Javadoc)
     * @see org.springframework.data.repository.CrudRepository#delete(java.lang.Object)
     */
    @Override
    @Transactional
    @SuppressWarnings("unchecked")
    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));
    }

相关问题