{"record":{"id":"2c06cf1622d07f81","repo":"alibaba/spring-ai-alibaba","slug":"failed-to-delete-dataset-version","errorCode":null,"errorMessage":"Failed to delete dataset version","messagePattern":"Failed to delete dataset version","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/service/impl/DatasetVersionServiceImpl.java","lineNumber":195,"sourceCode":"    public void deleteById(Long id) {\n        log.info(\"Deleting dataset version: {}\", id);\n        \n        if (id == null) {\n            throw new IllegalArgumentException(\"Version ID cannot be null\");\n        }\n\n        DatasetVersionDO existingVersion = datasetVersionMapper.selectById(id);\n        if (existingVersion == null) {\n            throw new IllegalArgumentException(\"Dataset version not found: \" + id);\n        }\n\n        if (\"PUBLISHED\".equals(existingVersion.getStatus())) {\n            throw new IllegalStateException(\"Cannot delete published version: \" + id);\n        }\n\n        int result = datasetVersionMapper.deleteById(id);\n        if (result <= 0) {\n            throw new RuntimeException(\"Failed to delete dataset version\");\n        }\n\n        log.info(\"Dataset version deleted successfully: {}\", id);\n    }\n\n    @Override\n    public PageResult<Experiment> getExperiments(DatasetExperimentsListRequest request) {\n        long offset = (request.getPageNumber() - 1L) * request.getPageSize();\n\n        List<ExperimentDO> experimentDOList = experimentMapper.selectByDatasetId(request.getDatasetId(), offset, request.getPageSize());\n\n        Integer totalCount = experimentMapper.selectCountByDatasetId(request.getDatasetId());\n\n        return new PageResult<>(\n                (long) totalCount,\n                (long) request.getPageNumber(),\n                (long) request.getPageSize(),\n                experimentDOList.stream()","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/service/impl/DatasetVersionServiceImpl.java#L177-L213","documentation":"After passing the null/existence/PUBLISHED checks, deleteById() executes datasetVersionMapper.deleteById(id) and throws RuntimeException(\"Failed to delete dataset version\") when the affected-row count is <= 0. This indicates the DELETE statement removed no rows despite the earlier existence check — typically a race with a concurrent deletion or a mapper/SQL issue.","triggerScenarios":"Another transaction deleted the version between the selectById existence check and deleteById; the mapper's delete SQL is misconfigured or filtered; database-level failure reported as 0 affected rows.","commonSituations":"Concurrent admin sessions deleting the same version; retry logic that double-executes deletes; Flyway/migration changes altering table names the mapper still targets.","solutions":["Retry once: if the version is gone, the delete already succeeded elsewhere — treat as success.","Verify the mapper's deleteById SQL targets the correct table.","Wrap delete in a short transaction or use DELETE ... WHERE id=? rowcount semantics with idempotent handling."],"exampleFix":"// before\nint result = datasetVersionMapper.deleteById(id);\nif (result <= 0) { throw new RuntimeException(\"Failed to delete dataset version\"); }\n// after\nint result = datasetVersionMapper.deleteById(id);\nif (result <= 0 && datasetVersionMapper.selectById(id) != null) {\n    throw new RuntimeException(\"Failed to delete dataset version\");\n} // else: already deleted concurrently — idempotent success","handlingStrategy":"retry","validationCode":"if (service.getById(id) == null) {\n    return; // nothing to delete\n}","typeGuard":null,"tryCatchPattern":"try {\n    service.deleteById(id);\n} catch (RuntimeException e) {\n    if (service.getById(id) == null) {\n        log.info(\"Version {} already deleted concurrently\", id);\n    } else { throw e; }\n}","preventionTips":["Handle deletes idempotently: row-count 0 plus row-gone means success.","Avoid concurrent admin sessions deleting the same version; use soft-delete flags if concurrency is common.","Keep mapper delete SQL aligned with the actual table schema after migrations."],"tags":["database","delete-failed","race-condition","dataset-version"],"backgroundTag":"database-write-failed","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}