2

我有一个报告运行器聚合,它正在处理报告运行命令。聚合具有目标标识符,并且两个命令具有相同的目标标识符。

收到以下错误

java.lang.IllegalArgumentException:工作单元在 org.axonframework.common.Assert.isTrue(Assert.java:54) ~[axon-core-3.0.6.jar:3.0.6 处已经有一个具有相同标识符的聚合] 在 org.axonframework.commandhandling.model.AbstractRepository.newInstance(AbstractRepository.java:84) ~[axon-core-3.0.6.jar:3.0.6] 在 org.axonframework.commandhandling.AggregateAnnotationCommandHandler$AggregateConstructorCommandHandler.handle(AggregateAnnotationCommandHandler .java:181) ~[axon-core-3.0.6.jar:3.0.6] 在 org.axonframework.commandhandling.AggregateAnnotationCommandHandler$AggregateConstructorCommandHandler.handle(AggregateAnnotationCommandHandler.java:170) ~[axon-core-3.0.6。 jar:3.0.6] 在 org.axonframework.commandhandling.AggregateAnnotationCommandHandler.handle(AggregateAnnotationCommandHandler.java:148) ~[axon-core-3.0.6.jar:3.0.6] 在 org.axonframework.commandhandling.AggregateAnnotationCommandHandler.handle(AggregateAnnotationCommandHandler.java:40) ~[axon-core-3.0.6.jar:3.0.6]

就像是

public class ExecuteReportsAggregate
{
    @AggregateIdentifier
    private String reportId; 

    // Command Handler and Even Source Handlers
}

执行报告命令

@Value
public class ExecuteReportCommand
{
    @TargetAggregateIdentifier
    String reportId;
}

报告执行的命令

@Value
public class ReportExecutedCommand
{
    // @TargetAggregateIdentifier
    private String reportId;
}

弹簧靴看起来像这样

public static void main(String[] args)
{
    ConfigurableApplicationContext config = SpringApplication.run(SsmpPreopenCommand.class, args);
    CommandBus commandBus = config.getBean(CommandBus.class);

    commandBus.dispatch(GenericCommandMessage.asCommandMessage(new ExecuteReportCommand("12345",
        "asdfasdf Errors", "/home/teo", new ServiceCredentials())));

    // commandBus.dispatch(GenericCommandMessage.asCommandMessage(new
    // ReportExecutedCommand("12345")));
}
4

1 回答 1

2

Axon 正在处理您实现的聚合实例。@CommandHandler因此,您可以通过使用注释标记 Aggregate 的相关方法。

(通常)聚合应该有:

  • 无参数构造函数
  • 具有命令作为第一个参数的构造函数,由@CommandHandler注释标记
  • 至少一个标有@EventSourcingHandler注释的方法,接受作为第一个参数的事件,该事件由AggregateLifecycle#apply()方法执行的构造函数的执行触发,并设置由 . 标记的字段AggregateIdentifier
  • 接受命令作为第一个参数的任意数量的其他方法,其中标有@CommandHandler注释
  • 任何数量的其他方法接受一个事件作为第一个参数,用@EventSourcingHandler注释标记

如果您在 上发送第一个命令CommandBus,Axon 将尝试找到具有匹配标识符的 Aggegate,并且由于它不存在,因此通过调用构造函数并将命令传递给它来创建它。构造函数将调用该AggregateLifecycle#apply()方法并触发事件(由 Axon 存储),因此从这个时间点开始,Axon 将尝试将所有具有相同命令的命令发送TargetAggregateIdentifier到此聚合实例。

如果您尝试使用 SAME 聚合标识符创建(并存储)另一个 SAME 类型的 Aggregate 实例,您将失败并看到上面的异常。

为避免,您想使用“create-on-check-fail”模式。在这里看看我的想法......

亲切的问候,

西蒙

于 2018-02-05T17:17:15.473 回答