14. Soft Delete Architecture & JPA Filtering

Logical Deletion Semantics & Entity Mapping

Master soft delete mechanics, database existence vs application visibility boundaries, PATCH vs DELETE semantics, entity mapping, and state machines.

Logical Deletion Semantics & Entity Mapping

Soft Delete is a deletion strategy where an application does not physically destroy a database row. Instead, it mutates a status flag—such as is_deleted—to mark the record as logically inactive.

Hard Delete:  DELETE FROM students WHERE id = 1   ──► Row physically destroyed
Soft Delete:  UPDATE students SET is_deleted = true ──► Row physically retained, logically hidden

1. High-Level Concept & The Archive Cabinet Analogy

Think of a filing cabinet at a university registrar's office:

THE ARCHIVE CABINET ANALOGY:
├── Active Student Record   ──► File remains in the active drawer (is_deleted = false)
├── Archived Student Record ──► File is stamped "ARCHIVED" and moved to rear storage (is_deleted = true)
├── Hard Delete Operation   ──► Shredding the paper file permanently
└── Soft Delete Operation   ──► Stamping the file "ARCHIVED" without destroying it
Database / API ConceptArchive Cabinet EquivalentOperational Role
Database RowStudent Paper FilePhysical container of record data
is_deleted = falseActive FileVisible to normal everyday operations
is_deleted = trueArchived FileRetained for audit/history, hidden from normal reads
PATCH /soft-deleteStamp "ARCHIVED"Partial state update operation
DELETE /students/{id}Paper ShredderPermanent physical row destruction

Core Architectural Rule: Physical database existence and application-level visibility are distinct concepts. Soft deletion changes a row's state; application queries must enforce visibility filtering rules.


2. Hard Delete vs Soft Delete Comparison

Property MetricHard Delete (DELETE)Soft Delete (PATCH /soft-delete)
Database StateRow physically removedRow physically retained
HTTP Verb SemanticsDELETE /api/students/{id}PATCH /api/students/{id}/soft-delete
Data Audit TrailLost permanentlyFully preserved
Application RecoveryDifficult (requires DB backups)Simple (toggle is_deleted = false)
Query RequirementStandard SQL queriesQueries MUST explicitly filter WHERE is_deleted = false

3. Entity Mapping: Boolean vs Primitive boolean

@Entity
@Table(name = "students")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @Column(name = "is_deleted", nullable = false)
    private Boolean isDeleted = false; // Initialized to active state

    public Student() {}

    public Long getId() { return id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public Boolean getIsDeleted() { return isDeleted; }
    public void setIsDeleted(Boolean isDeleted) { this.isDeleted = isDeleted; }
}

[!WARNING] Nullability Trap: Wrapper Boolean allows three states (true, false, null). If null has no business meaning, enforce non-null integrity at the database column level (nullable = false) or use primitive boolean to prevent null visibility bugs.


4. Entity State Machine Transitions

Active SoftDeleted Save Entity (is_deleted = false) PATCH /soft-delete (is_deleted = true) Restore Operation (is_deleted = false) Hard Delete (DELETE) Hard Delete (DELETE) PhysicalDestruction VisibleToAPIs HiddenFromNormalAPIs AuditTrailRetained

❓ Knowledge Check

Knowledge Check

What is the fundamental difference between hard delete and soft delete at the database level?

Knowledge Check

Why is PATCH preferred over DELETE for soft-deletion HTTP endpoints?

On this page