多实体聚合命令处理

剑圣

我有一个这样的聚合根:

聚合根:

@NoArgsConstructor
@Aggregate(repository = "positionAggregateRepository")
@AggregateRoot
@XSlf4j
@Data
public class HopAggregate {

@AggregateIdentifier
private String hopId;
private FilteredPosition position;
private LocalDate positionDate;
@AggregateMember
private Security security;

@CommandHandler
public HopAggregate(NewHopCommand cmd) {
    log.info("creating new position , {}", cmd.getDateId());
    apply(new HopEvent(cmd.getHopId(), cmd.getDateId(), cmd.getFilteredPosition(), cmd.getSecurity(), false));
}

@CommandHandler
public void handle(UpdateHopCommand cmd) {
    log.info("creating hop update event {}", cmd);
    apply(new HopEvent(this.hopId, this.positionDate, cmd.getFilteredPosition(), this.security, true));
}

@CommandHandler
public void handle(SecurityUpdate cmd) {
    log.info("updating security {}", cmd);
    apply(new SecurityUpdateEvent(this.hopId, cmd.getFilteredSecurity()));
}

@EventSourcingHandler
public void on(HopEvent evt) {
    if (evt.getIsUpdate()) {
        log.info("updating position {}", evt);
        this.position = evt.getFilteredPosition();
    } else {
        log.info("adding new position to date {}", evt);
        this.hopId = evt.getHopId();
        this.positionDate = evt.getDate();
        this.position = evt.getFilteredPosition();
        this.security= evt.getSecurity();
    }
}

@EventSourcingHandler
public void on(SecurityUpdateEvent evt) {
    log.info("hop id {}, security update {}", this.hopId, evt.getFilteredSecurity().getSecurityId());
}

}

子实体:

@XSlf4j
@Data
@RequiredArgsConstructor
@NoArgsConstructor
public class IpaSecurity implements Serializable {

@EntityId
@NonNull
private String id;
@NonNull
private FilteredSecurity security;
}

我的问题是,当我像这样推送和更新时:

@EventHandler
public void handleSecurityEvent(SecurityUpdate securityUpdate) {
log.info("got security event {}", securityUpdate);
commandGateway.send(securityUpdate);
}

我的命令是:

@Data
@RequiredArgsConstructor
@NoArgsConstructor
@ToString
public class SecurityUpdate {

@NonNull
@TargetAggregateIdentifier
private String id;
@NonNull
private FilteredSecurity filteredSecurity;
}

我越来越聚合根未找到异常:

命令'com.hb.apps.ipa.events.SecurityUpdate'导致org.axonframework.modelling.command.AggregateNotFoundException(在事件存储中未找到该集合)

我不确定如何处理这种情况。我的要求是,每个聚合都应检查其是否包含安全性,然后在发出命令时对其进行更新。我想念什么?让我知道您是否需要有关代码的更多信息。

谢谢你的帮助。

史蒂文

命令始终针对单个实体该实体可以是集合,包含在集合(Axon Framework称为集合成员)中的实体或简单的单例组件。但是要注意的重要一点是,只有一个实体可以处理该命令。

这就是要求您@TargetAggregateIdentifier在Axon的Command中设置in的功能,以便在有问题的Command Handler属于其中的情况下,才能将其路由到单个Aggregate实例。

AggregateNotFoundException你得到的信号是,@TargetAggregateIdentifier在你的注释字段SecurityUpdate命令确实没有对应于任何现有的聚集。因此,我怀疑中的id字段SecurityUpdate@AggregateIdentifier您的HopAggregate聚合中的任何带注释的字段都不对应

除上述内容外,在查看您要与您分享的摘要时,我还有其他一些建议:

  • @Aggregate用进行元注释@AggregateRoot因此,您不需要在Aggregate类上同时指定两者
  • 要记录正在处理的消息,可以使用LoggingInterceptor您可以在任何能够处理消息的组件上进行配置,从而提供一种通用的日志记录方式。这将省略在消息处理功能中添加日志行的必要性
  • 您将HopEvent同时在create和update命令上发布。这样做会使您HopEvent非常通用。理想情况下,您的事件可以阐明系统中发生的业务操作。我的经验法则通常是这样的:“如果我将事件类告诉我的业务经理/客户,那么他/她应该确切知道它的作用”。因此,我建议将事件重命名为更具体的名称
  • 与一样HopEventUpdateHopCommand都是非常通用的。您的命令应表达在应用程序中执行操作的意图。用户通常不希望更新,例如,他们希望地址更改。您的命令类理想地反映了这一点
  • 建议的命令命名约定以当前时态以动词开头。因此,它不应该是SecurityUpdate,而是UpdateSecurity命令是表达意图的请求,消息理想地反映了这一点

希望这可以帮助您@juggernaut!

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

TOP 榜单

热门标签

归档