Java 为什么名称派生的JPA查询方法如此有效?

Java 为什么名称派生的JPA查询方法如此有效?,java,spring,jpa,spring-data-jpa,spring-data,Java,Spring,Jpa,Spring Data Jpa,Spring Data,我有一个存储库接口和名称派生的查询方法: int deleteAllBySpaceIdAndUserId(UUID spaceId, UUID userId); 调用此方法会导致先选择查询,然后删除查询 发布select的目的是什么?为什么不作为单个查询进行计算? 为什么我需要它以这种(奇怪的)方式工作?Spring Data不执行直接SQL查询来删除实体,而是使用EntityManager及其remove方法 例如,您可以查看org.springframework.data.jpa.repo

我有一个存储库接口和名称派生的查询方法:

int deleteAllBySpaceIdAndUserId(UUID spaceId, UUID userId);
调用此方法会导致先选择查询,然后删除查询

发布select的目的是什么?为什么不作为单个查询进行计算?
为什么我需要它以这种(奇怪的)方式工作?

Spring Data不执行直接SQL查询来删除实体,而是使用EntityManager及其remove方法

例如,您可以查看org.springframework.data.jpa.repository.support.simplejpeparepository类,该类提供了默认方法(例如deleteById等)的实现:

公共作废删除(T实体){
Assert.notNull(实体,“实体不能为null!”);
if(entityInformation.isNew(实体)){
返回;
}
类类型=ProxyUtils.getUserClass(实体);
T existing=(T)em.find(type,entityInformation.getId(entity));
//如果要删除的实体不存在,则delete是NOOP
if(现有==null){
返回;
}
em.remove(em.contains(实体)?实体:em.merge(实体));
}

由于EntityManager的remove方法获取实体对象本身,而不仅仅是ID值或类似值,因此Spring Data必须使用所选参数(ID或案例2中的值)执行find方法,获取实际的实体对象,然后将其从EntityManager中删除。

您能确认它是导致JPQL选择还是仅导致SQL选择吗?这似乎是查询生成器的一个重大改进机会,然后,对于
deleteAll
。谢谢您的回答。但是为什么人们可以选择这种非有效的方式来删除实体而不是单个查询呢?这是一个你必须向Spring数据开发人员提出的问题。我猜这与比简单的平面表更复杂的映射有关,因为实体的结构不必在数据库中复制,从而留下了不一致的数据。
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));
}