英文:
How can I delete an AggregateMember on Axon?
问题
我有一个聚合Organization
,它可以有多个地址。因此,我们将OrganizationDeliveryAddress
建模为一个聚合成员。在OrganizationDeliveryAddress
上,我们为实体本身编写了命令和事件处理程序。
以下是我目前的实现:
@Aggregate
public class Organization {
private @AggregateIdentifier
@NonNull UUID organizationId;
@AggregateMember
private final List<OrganizationDeliveryAddress> deliveryAddresses = new ArrayList<>();
@CommandHandler
public UUID on(AddOrganizationDeliveryAddressCommand command) {
val addressId = UUID.randomUUID();
val event = new OrganizationDeliveryAddressAddedEvent(command.getOrganizationId(), addressId, command.getAddress());
AggregateLifecycle.apply(event);
return addressId;
}
@EventSourcingHandler
public void on(OrganizationDeliveryAddressAddedEvent event) {
val address = new OrganizationDeliveryAddress(event.getOrganizationDeliveryAddressId(), false);
deliveryAddresses.add(address);
}
}
public class OrganizationDeliveryAddress {
private @EntityId
@NonNull UUID organizationDeliveryAddressId;
@CommandHandler
public void on(RemoveOrganizationDeliveryAddressCommand command) {
AggregateLifecycle.apply(new OrganizationDeliveryAddressRemovedEvent(command.getOrganizationId(),
command.getOrganizationDeliveryAddressId()));
}
@EventSourcingHandler
public void on(@SuppressWarnings("unused") OrganizationDeliveryAddressRemovedEvent event) {
if (organizationDeliveryAddressId.equals(event.getOrganizationDeliveryAddressId())) {
AggregateLifecycle.markDeleted();
}
}
}
我们想要删除其中一个地址,但看起来不仅地址被删除了,整个聚合也被删除了。
因此,这是我的问题:我如何指示Axon Framework删除OrganizationDeliveryAddress
聚合成员?
英文:
I have an aggregate Organization
which can have several addresses. So we have modeled this OrganizationDeliveryAddress
as an Aggregate Member. On the OrganizationDeliveryAddress
we command and event sourcing handlers for the entity itself.
Here's my current implementation:
@Aggregate
public class Organization {
private @AggregateIdentifier
@NonNull UUID organizationId;
@AggregateMember
private final List<OrganizationDeliveryAddress> deliveryAddresses = new ArrayList<>();
@CommandHandler
public UUID on(AddOrganizationDeliveryAddressCommand command) {
val addressId = UUID.randomUUID();
val event = new OrganizationDeliveryAddressAddedEvent(command.getOrganizationId(), addressId, command.getAddress());
AggregateLifecycle.apply(event);
return addressId;
}
@EventSourcingHandler
public void on(OrganizationDeliveryAddressAddedEvent event) {
val address = new OrganizationDeliveryAddress(event.getOrganizationDeliveryAddressId(), false);
deliveryAddresses.add(address);
}
}
public class OrganizationDeliveryAddress {
private @EntityId
@NonNull UUID organizationDeliveryAddressId;
@CommandHandler
public void on(RemoveOrganizationDeliveryAddressCommand command) {
AggregateLifecycle.apply(new OrganizationDeliveryAddressRemovedEvent(command.getOrganizationId(),
command.getOrganizationDeliveryAddressId()));
}
@EventSourcingHandler
public void on(@SuppressWarnings("unused") OrganizationDeliveryAddressRemovedEvent event) {
if (organizationDeliveryAddressId.equals(event.getOrganizationDeliveryAddressId())) {
AggregateLifecycle.markDeleted();
}
}
}
We want to remove one of the addresses, but it looks like not just the address, but the entire aggregate is deleted.
So here's my question: How can I instruct Axon Framework to remove the OrganizationDeliveryAddress
Aggregate Member?
答案1
得分: 4
AggregateMember
并不是一个独立的聚合,而只是另一个聚合的成员。这就是为什么,如果你调用 AggregateLifecycle.markDeleted();
,它会将聚合本身标记为已删除。
要想“删除”一个 AggregateMember
,你应该执行与添加相反的操作,这意味着你可以在你的聚合上有一个 @EventSourcingHandler
方法,监听 OrganizationDeliveryAddressRemovedEvent
事件。这个方法将负责在你的聚合成员(deliveryAddresses
)上查找正确的 DeliveryAddress
,或者更好的方法是从一个 Map
中移除,正如下面你将看到的,伪代码如下:
// Organization.java
...
@AggregateMember
private final Map<UUID, OrganizationDeliveryAddress> deliveryAddressItToDeliveryAddress = new HashMap<>();
...
@EventSourcingHandler
public void on(@SuppressWarnings("unused") OrganizationDeliveryAddressRemovedEvent event) {
Assert.isTrue(deliveryAddressItToDeliveryAddress.containsKey(event.getOrganizationDeliveryAddressId()), "We do not know about this address");
deliveryAddressItToDeliveryAddress.remove(event.getOrganizationDeliveryAddressId());
}
英文:
The AggregateMember
is not an Aggregate per se but just a member of another Aggregate. This is why if you call AggregateLifecycle.markDeleted();
it will mark the Aggregate itself as deleted.
To 'delete' an AggregateMember
you should do the opposite as adding it, which means you can have an @EventSourcingHandler
method on your Aggregate listening to the OrganizationDeliveryAddressRemovedEvent
. This method would be responsible to find the right DeliveryAddress on your AggregateMember (deliveryAddresses
) or even better a Map
as you will see below and simply remove it from that. A pseudo-code could be something like this:
// Organization.java
...
@AggregateMember
private final Map<UUID, OrganizationDeliveryAddress> deliveryAddressItToDeliveryAddress = new HashMap<>();
...
@EventSourcingHandler
public void on(@SuppressWarnings("unused") OrganizationDeliveryAddressRemovedEvent event) {
Assert.isTrue(deliveryAddressItToDeliveryAddress.containsKey(event.getOrganizationDeliveryAddressId()), "We do not know about this address");
deliveryAddressItToDeliveryAddress.remove(event.getOrganizationDeliveryAddressId());
}
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论