问题:客户的技术限制迫使我在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测试聚合状态并避免错误?
答案 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
希望一切都清楚
Corrado。