The logic is: publish an event to notify closing a netty channel. Before, through DomainEventPublish
, I publish the event at domain service, application service, or catch
. Now, I found that it was wrong because only aggregate root can publish domain event.
I plan to refactor the way of publishing domain events to using Spring Data Common. I can design an aggregate root named ChannelToClose
, and with a method that will register the NeedClose
event, but I can't publish the registered events. Spring Data Common publishes the registered events only when executing save()
of a repository, so I don't know how to publish events when aggregate root doesn't need to be persisted.
This is the comment of org.springframework.data.domain.DomainEvents
:
DomainEvents can be used on methods of aggregate roots managed by Spring Data repositories to publish the events returned by that method as Spring application events.
TL;DR:
Just call save
anyway or manually register events using an ApplicationEventPublisher
.
Some background:
The underlying problem is that JPA doesn't really lend it well to DDD.
Since it saves everything that changed inside the session there is no easy hook to put the required event handling in.
One might consider inspecting the session itself or relying on JPAs lifecycle events, but these are based on entities with no (clear) way to identify the Aggregate Root it belongs to.
Imagine an Order
of which you change the quantity
in one of its LineItem
s. JPA will fire an event for the LineItem
but not for the Order
, but the Order
is the Aggregate Root that should fire the events.
So either way, it is a leaky abstraction. Spring Data went with relying on the save-method which works for most (all?) other stores. These stores most of the time have a much clearer way to identify Aggregates. MongoDb for example has Documents which pretty much are a 1:1 fit to Aggregates.