为什么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));
}
这段代码对我来说似乎过于简单了。 你觉得怎么样?
答案 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时删除,否则没有必要删除它。
恕我直言你的测试是错误的。首先,您要保留要删除的实体。