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 Domain Events Laravel Package

swag-industries/doctrine-domain-events

Adds Doctrine domain event support to Laravel: entities can record domain events, and the package collects and dispatches them through Laravel’s event system after Doctrine flushes or transactions commit, keeping persistence and side effects cleanly separated.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The package implements the canonical "record domain events on the aggregate, collect and dispatch after flush" pattern. It hooks into Doctrine ORM via an event subscriber/listener on the EntityManager, so it is framework-agnostic at its core. Fit for a Laravel codebase is therefore binary: it is a strong fit if Doctrine is already the persistence layer (e.g., via laravel-doctrine/orm or a Symfony-derived service), and it is not an integration at all if the app is Eloquent-based. Eloquent models have no relationship to this package; adopting it there means adopting Doctrine, which is an ORM migration project, not a package adoption.

Integration feasibility. The surface area is small: a trait (or interface + trait) applied to entities to record events, plus a subscriber registered on the EntityManager's event manager. Wiring is a handful of lines in a service provider or Doctrine config. Assuming Doctrine is present, the technical lift is low and can be validated in a single spike.

Technical risk. Adoption is the dominant risk: 4 stars, 0 dependents, and a single small maintainer entity means effectively no battle-testing in the wild and no ecosystem pressure to keep it correct. The mitigating factor is that the code is small enough — likely a few hundred lines — to audit in an afternoon and vendor under MIT. The real correctness risk is transactional semantics: whether events are released before or after dispatch (at-most-once vs. at-least-once), whether events can be dispatched for a transaction that later rolls back, whether a flush triggered inside an event handler re-enters collection correctly, and whether events recorded on removed or embedded entities are handled. These are the questions that decide production safety, and they must be answered from source, not from README.

Key questions.

  • Which dispatcher abstraction is required — PSR-14, Symfony EventDispatcher contracts, or a bespoke interface? This determines whether a Laravel bridge is trivial or requires an adapter.
  • Is dispatch on postFlush, onFlush, or postPersist? Doctrine has no native post-commit hook, so "after flush" is not the same as "after commit."
  • Are collected events cleared before dispatch (events lost on handler throw) or after (possible duplicate dispatch on retry)?
  • How are events on removed entities, embeddables, and collection-only changes collected?
  • What reentrancy protection exists if a listener triggers another flush?
  • What are the PHP and Doctrine ORM version constraints, and is there a CI matrix and test suite covering rollback and reentrancy?
  • Does it support multiple entity managers, and how is the dispatcher injected per manager?

Integration Approach

Stack fit. Applicable wherever Doctrine is the ORM: Symfony services, laravel-doctrine in a Laravel app, or framework-free PHP workers. Also useful as a shared domain package across multiple services if you already standardize on Doctrine. It is not applicable to Eloquent models and should not be forced onto a predominantly Eloquent codebase to chase DDD aesthetics.

Migration path. Introduce per bounded context, not globally. Start by applying the trait to new or newly refactored aggregates only; leave legacy entities untouched. Register the subscriber once per entity manager. If the codebase has an existing in-house event-recording mechanism, keep it until the new path is verified in production — do not run both collectors over the same entities, or you will double-dispatch.

Compatibility. The key compatibility question is dispatcher contract alignment. If the package targets Symfony contracts, a thin adapter over Laravel's Illuminate\Contracts\Events\Dispatcher is needed; if it targets PSR-14, Laravel can be bridged with a small wrapper. Pin PHP and doctrine/orm versions explicitly, and confirm the package's constraints do not conflict with the rest of the dependency graph. Verify it works with whichever transaction wrapper your app uses (DB::transaction, Doctrine's Transactional, or explicit begin/commit).

Sequencing.

  1. Source audit and test-suite review focused on the transactional semantics above; timebox to one to two days.
  2. Spike in one bounded context with a single aggregate and one handler, including a forced rollback to observe event behavior.
  3. Add observability — log event name, aggregate ID, and dispatch time — before expanding.
  4. Decide between dependency vs. vendoring. Given the code size and MIT license, vendoring into the repo is cheap insurance and removes supply-chain risk entirely.
  5. Expand context by context once the semantics are proven.

Operational Impact

Maintenance. Low churn, small dependency, MIT license — cheap to carry. The real maintenance risk is abandonment, which vendoring neutralizes at near-zero cost. Budget a small recurring review of the vendored copy against upstream.

Support. Community best-effort only. Assume no vendor SLA, no guaranteed security response, and thin documentation. Internal ownership — an engineer who understands Doctrine's lifecycle — is mandatory. Do not adopt without a named owner.

Scaling. Event collection is in-memory per request and negligible in volume. Dispatch is synchronous by default, so handlers doing I/O will inflate request latency and widen the transaction window if dispatch is inside the transaction. Heavy handlers should be converted to queued jobs, which means the event objects must be serializable — verify that before designing handlers around them. On long-running workers, confirm events are cleared per unit of work to avoid unbounded accumulation across requests.

Failure modes. The ones to plan for: events dispatched for transactions that subsequently roll back (if dispatch sits at postFlush rather than after commit); partial dispatch when a handler throws mid-iteration, leaving remaining events undelivered and the entity manager possibly closed; duplicate delivery on retry when dispatch precedes clearing; silent no-op if the subscriber is not registered on the correct entity manager; and handlers that flush, producing reentrant collection behavior. Each of these needs a documented answer and, ideally, a test in your own suite rather than reliance on upstream coverage.

Ramp-up. The learning curve is Doctrine entity lifecycle and aggregate design discipline, not the package itself. Laravel-native engineers typically have neither, so onboarding cost is real. Write a short internal convention doc covering when to record events, what belongs in an event, dispatcher wiring, and the sync-vs-queue rule for handlers before the second team adopts it.

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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums