Spring JPA 不能删除 id 为 0 的数据

Spring JPA 不能删除 id 为 0 的数据

Spring Data JPA 的 Repository 不能删除 id 为数值类型(Integer、Long 等),且值为 0 的对象

源码中逻辑是,如果 ((Number)id).longValue() == 0L,则跳过删除

(源码中这样写,具体原因目前不清楚)

Debug 流程如下:

SimpleJavaRepository.java 是默认的 JpaRepository 实现,其中delete 代码如下

@Transactional
public void delete(T entity) {
    Assert.notNull(entity, "Entity must not be null!");
    if (!this.entityInformation.isNew(entity)) { // <<<- Debug 进 isNew 方法
        Class<?> type = ProxyUtils.getUserClass(entity);
        T existing = this.em.find(type, this.entityInformation.getId(entity));
        if (existing != null) {
            this.em.remove(this.em.contains(entity) ? entity : this.em.merge(entity));
        }
    }
}

this.entityInformation.isNew(entity) 这句在 JpaMetamodelEntityInformation.java 中:

public boolean isNew(T entity) {
    if (this.versionAttribute.isPresent() && !(Boolean)this.versionAttribute.map(Attribute::getJavaType).map(Class::isPrimitive).orElse(false)) {
        BeanWrapper wrapper = new DirectFieldAccessFallbackBeanWrapper(entity);
        return (Boolean)this.versionAttribute.map((it) -> {
            return wrapper.getPropertyValue(it.getName()) == null;
        }).orElse(true);
    } else {
        return super.isNew(entity); // <<<- Debug 进 isNew 方法
    }
}

再往下走,AbstractEntityInformation.java

public boolean isNew(T entity) {
    ID id = this.getId(entity);
    Class<ID> idType = this.getIdType();
    if (!idType.isPrimitive()) {
        return id == null;
    } else if (id instanceof Number) {
        return ((Number)id).longValue() == 0L; // <<<- 在这里返回 true
    } else {
        throw new IllegalArgumentException(String.format("Unsupported primitive id type %s!", idType));
    }
}

isNew 方法在判断 ((Number)id).longValue() == 0L 时返回了 ture,所以 delete 方法跳过了删除

你可能感兴趣的:(Spring,jpa,spring,java)