为什么repository.delete(entity_with_id_null)启动SQL INSERT + DELETE

时间:2017-05-31 06:28:53

标签: spring jpa spring-data-jpa

为什么repository.delete(entity_With_Null_Id)启动SQL INSERT + DELETE

使用存储库并尝试删除id为== null的实体,启动2个不必要的SQL命令,并且没有例外!

    @Test
    public void removeWithIdNull() {

        // ARRANGE
        Info infoWithIdNull = new Info("entity with id null");
        List<Info> listA = infoRepository.findAll();
        assertThat(listA, hasSize(0));

        // ACT
        infoRepository.delete(infoWithIdNull);

        // ASSERT
        List<Info> listResult = infoRepository.findAll();
        assertThat(listResult, hasSize(0));

    }

这将生成以下SQL: INSERT然后是DELETE =&gt;

    DEBUG org.hibernate.SQL - insert into info (message, version, id) values (?, ?, ?)
    TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - [entity with id null] 
    TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [2] as [INTEGER] - [0] 
    TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [3] as [BIGINT] - [10] 

    DEBUG org.hibernate.SQL - delete from info where id=? and version=? 
    TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [BIGINT] - [10]
    TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [2] as [INTEGER] - [0]

这真让我烦恼,为什么Spring-Data-JPA在删除之前不检查实体是否存在,而不是进行merge()..

Data-JPA SimpleJpaRepository中的代码解释了这种行为:

    @Transactional
    public void delete(T entity) {

        Assert.notNull(entity, "The entity must not be null!");
        em.remove(em.contains(entity) ? entity : em.merge(entity));
    }

这段代码对我来说似乎过于简单了。 你觉得怎么样?

3 个答案:

答案 0 :(得分:0)

让我们分析代码

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

您询问em是否包含实体,然后是remove它,否则merge然后remove包含该实体, merge操作生成insert语句

答案 1 :(得分:0)

我最终在JIRA上发帖,并且该问题现在在spring-data-jpa 2.2版本中已修复。 这被认为是一个真正的问题。 https://jira.spring.io/browse/DATAJPA-1535

答案 2 :(得分:-1)

我不明白你的问题。您想要删除实际上未映射到任何数据库行的实体。

你期待什么?我们只讨论当db中的实体是PRESENT时删除,否则没有必要删除它。

恕我直言你的测试是错误的。首先,您要保留要删除的实体。