Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Doctrine Cascade Soft Delete Bundle Laravel Package

wernerdweight/doctrine-cascade-soft-delete-bundle

wernerdweight/doctrine-cascade-soft-delete-bundle adds cascade soft-delete support to Doctrine entities in Symfony, helping related records be marked as deleted alongside their parent while respecting entity associations and configurable cascade behavior.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit — This is a Symfony bundle, not a Laravel package, and that distinction drives the entire assessment. It targets a narrow but real gap: Doctrine ORM's cascade: [remove] does not fire for soft deletes, because a soft delete is a flush-time UPDATE, not a lifecycle removal. The bundle works by attaching a Doctrine event subscriber/listener that intercepts the soft-delete event and walks associations to mark children as deleted. Architecturally that means it sits inside your persistence layer and mutates UnitOfWork state — a high-blast-radius position for a dependency with 0 stars, 0 dependents, and a last release of 2023-02-21. Treat it as reference implementation, not as a library you adopt blind.

Integration feasibility — The mechanics are cheap: one Composer require, one bundle registration, one entity-level attribute/config. The real feasibility question is the compatibility matrix. A Feb-2023 release predates Symfony 7 (Nov 2023) and Doctrine ORM 3.0 (Feb 2024), so constraint widening is likely required before it will install on a current stack. It also presumes a specific soft-delete implementation (Gedmo SoftDeleteable or its own contract) — verify which, because that dictates whether it composes with your existing entity base classes and audit tooling. Assume a fork on day one.

Technical risk — Concentrated in correctness, not security:

  • Silent partial cascade. If the listener errors mid-graph or misses an association type, the parent is soft-deleted and children are not. That is worse than no cascade, because the inconsistency is invisible until reporting breaks.
  • Graph traversal hazards. Cycles, self-referencing associations, and many-to-many join tables are the classic failure cases. Many-to-many is especially thorny — soft delete only works if the owning side owns the semantics, and join-table rows are typically untouched.
  • Collection hydration cost. Cascading means loading every associated collection into memory at delete time. A department with 200k child records becomes a 200k-row hydration inside a transaction.
  • Recursion guards. Whether a de-dup/visited set exists is the single most important line of code in the package.
  • Event ordering. Interaction with Gedmo listeners, audit logs, and workflow subscribers is unspecified and version-sensitive.

Key questions — (1) Which Doctrine ORM and Symfony versions are formally supported, and does it load on ORM 3? (2) Which soft-delete implementation does it contract against? (3) Does it handle ManyToMany, self-referencing, and cyclic graphs, and with what recursion guard? (4) Is cascade applied pre-flush inside the caller's transaction? (5) Is there CI and test coverage for cascade semantics, or is the repo effectively a code sample? (6) What is the restore/undelete story — does it cascade symmetrically, and do unique constraints collide? (7) Is there a maintained fork or upstream successor?

Integration Approach

Stack fit — Symfony + Doctrine ORM + soft delete is the only viable home. If the platform in question is Laravel-first, this package is a non-starter: Laravel's SoftDeletes trait has a completely different lifecycle, and the equivalent solution there is model-event hooks (deleting) or a first-party package such as soft-cascade. Confirm the actual stack before spending any evaluation cycles — the framing mismatch here is itself a signal that a decision-maker may be pattern-matching on the word "cascade" rather than on the runtime.

Migration path — Vendor the source into an internal namespace rather than depending on Packagist. The surface area is small enough that owning it is cheaper than managing a transitive dependency with one maintainer and zero downstream users. Concretely: copy the listener/subscriber into an internal bundle, widen Composer constraints, and replace the package dependency with your own.

Compatibility — Build a CI job that installs against your actual matrix (PHP 8.2/8.3, Symfony 6.4/7.x, Doctrine ORM 2.20/3.x, Gedmo version) before any application code is written. That job is the deliverable that tells you whether this is a two-day or two-month integration. Do not merge application wiring until it is green.

Sequencing

  1. Spike (1–2 days). Fork the repo, install in a throwaway Symfony skeleton with a three-entity graph containing a one-to-many, a many-to-many, and a self-reference. Observe what breaks.
  2. Test harness first. Write failing tests for cascade completeness, cycle safety, M2M behavior, transaction rollback, and restore symmetry. These tests are the asset — they outlive whatever implementation you choose.
  3. Build-vs-buy decision. Given 0 stars, 0 dependents, and an opportunity score of 20.2, the honest comparison is "fork a stale 2023 package" versus "write ~200 lines of an internal Doctrine listener against our own tests." The second is usually cheaper and always safer.
  4. Single bounded context. Roll out to one low-risk aggregate with a shallow graph; instrument row counts and query counts on delete.
  5. Expand or abandon. Promote to other contexts only after the first has survived a release cycle, including a restore/undelete incident.

Operational Impact

Maintenance — You will be the maintainer. A repository with zero stars and zero dependents generates no community pressure to fix Doctrine 3 or Symfony 7 breakage, and the original author has no obligation to respond. Budget recurring fork-rebase effort at every framework upgrade, or eliminate that cost by internalizing the code.

Support — No SLA, no vendor, GitHub issues only. That is acceptable for internal tooling and unacceptable for anything on a revenue path. Decide which this is before integration, not after.

Scaling — Cascade cost scales with graph breadth, not with the single row you deleted. Bulk operations (offboarding a tenant, archiving a workspace) will hydrate entire object trees, hold long transactions, and risk lock contention. Plan for application-level chunking and batch processing above the listener; the package itself offers no async or queue story. Watch query counts on delete paths the same way you watch them on read paths.

Failure modes — Ranked by severity: (1) silent partial cascade leaving orphaned live children under a soft-deleted parent; (2) infinite recursion on cyclic or self-referencing graphs; (3) missing join-table cleanup on many-to-many, producing phantom membership after "delete"; (4) unique-constraint collisions on restore; (5) listener ordering conflicts with audit/workflow subscribers that cause double-writes or skipped events; (6) timeout and transaction rollback on large graphs, which at least fails loudly. Each should have a monitoring signal — a nightly integrity query that counts children of soft-deleted parents is the cheapest possible insurance and should ship with the integration, not after it.

Ramp-up — The API learning curve is trivial: one bundle registration and one attribute. The actual cost is conceptual — engineers must understand Doctrine's UnitOfWork, flush-time semantics, and the difference between removal and soft deletion to reason about failures. A competent Symfony developer is productive in half a day; debugging a partial cascade without documentation takes considerably longer. Write the cascade contract down (which associations are covered, what happens on cycles, how restore behaves) as part of the integration, and treat that document as the primary deliverable alongside the code.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast