Axon状态存储的聚合测试IllegalStateException

时间:2020-07-23 08:00:37

标签: spring-boot axon

问题:客户的技术限制迫使我在PostgreSQL中将Axon与状态存储的聚合一起使用。我尝试了一个简单的JPA-Entity Axon-Test并得到了IllegalStateException。

研究:https://gitlab.com/ZonZonZon/simple-axon.git

上有此案的简化项目。

在我的测试中

fixture.givenState(MyAggregate::new)
    .when(command)
    .expectState(state -> {
      System.out.println();
    });

我明白了

无法检索此聚集的状态,因为已在回滚的工作单元中对其进行了修改 java.lang.IllegalStateException:无法检索此聚合的状态,因为已经在回滚的工作单元中对其进行了修改 在org.axonframework.common.Assert.state(Assert.java:44)

问题:如何使用Axon测试聚合状态并避免错误?

1 个答案:

答案 0 :(得分:1)

您的项目中缺少一些部分,以使测试正常运行。我将尝试尽可能简洁地解决它们:

  • 您的命令应包含将其连接到聚合的信息。 @TargetAggregateIdentifier是框架提供的注释,该框架将某个字段与其@AggregateIdentifier的对应字段连接到您的聚合中。您可以在https://docs.axoniq.io/reference-guide/implementing-domain-logic/command-handling/aggregate#handling-commands-in-an-aggregate处阅读更多内容。 这样说来,需要将UUID字段添加到您的Create命令中。

  • 此信息随后将传递到Created事件中:事件被存储,并且可以通过重播或汇总重新水化(在客户端重新启动时)进行处理。 (这些)是我们信息的真实来源。

  • @EventSourcingHandler注释方法将负责应用事件并更新@Aggregate

    public void on(Created event) {
         uuid = event.getUuid();
         login = event.getLogin();
         password = event.getPassword();
         token = event.getToken();
    }
    
  • 然后测试将变为

    public void a_VideochatAccount_Created_ToHaveData() {
    
       Create command = Create.builder()
                              .uuid(UUID.randomUUID())
                              .login("123")
                              .password("333")
                              .token("d00a1f49-9e37-4976-83ae-114726938c73")
                              .build();
    
       Created expectedEvent = Created.builder()
                                     .uuid(command.getUuid())
                                     .login(command.getLogin())
                                     .password(command.getPassword())
                                     .token(command.getToken())
                                     .build();
    
       fixture.givenNoPriorActivity()
              .when(command)
              .expectEvents(expectedEvent);
    }
    

此测试将验证您的CQRS的命令部分

然后,我建议将查询部分与您的@Aggregate分开:然后,您需要使用方法上带有@EventHandler批注的事件处理到投影{{ 1}}类,并实现将使用@Component JPA方式将所需信息存储到PostgreSQL @Entity中的逻辑部分,我相信您对此很熟悉用。 您可以在参考版本https://docs.axoniq.io/reference-guide/implementing-domain-logic/event-handling

中找到基于代码的“查询模型”视频示例之后的参考指南https://github.com/AxonIQ/food-ordering-demo/tree/master中找到有用的信息。

希望一切都清楚

Corrado。