如何在 Axon 上删除 AggregateMember?

huangapple go评论76阅读模式
英文:

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&lt;OrganizationDeliveryAddress&gt; deliveryAddresses = new ArrayList&lt;&gt;();

  @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(&quot;unused&quot;) 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&lt;UUID, OrganizationDeliveryAddress&gt; deliveryAddressItToDeliveryAddress = new HashMap&lt;&gt;();
...
@EventSourcingHandler
public void on(@SuppressWarnings(&quot;unused&quot;) OrganizationDeliveryAddressRemovedEvent event) {
    Assert.isTrue(deliveryAddressItToDeliveryAddress.containsKey(event.getOrganizationDeliveryAddressId()), &quot;We do not know about this address&quot;);
    deliveryAddressItToDeliveryAddress.remove(event.getOrganizationDeliveryAddressId());
}

</details>



huangapple
  • 本文由 发表于 2020年8月17日 18:19:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/63448894.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定