当前位置: 首页 > 知识库问答 >
问题:

轴突状态存储聚集在测试中的异常

吴鸿彩
2023-03-14

环境设置:Axon4.4,H2Database(作为CI的一部分,我们正在进行组件测试)代码如下所示。

    @Aggregate(repository = "ARepository")
    @Entity
    @DynamicUpdate
    @Table(name = "A")
    @Getter
    @Setter
    @NoArgsConstructor
    @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
    @Log4j2
    Class A implements Serializable {
    
    
      @CommandHandler
      public void handle(final Command1 c1) {
        apply(EventBuilder.buildEvent(c1));
      }
    
      @EventSourcingHandler
      public void on(final Event1 e1) {
      //some updates to the modela
        apply(new Event2());
      }
    
      @Id
      @AggregateIdentifier
      @EntityId
      @Column(name = "id", length = 40, nullable = false)
      private String id;
    
       @OneToMany(
          cascade = CascadeType.ALL,
          fetch = FetchType.LAZY,
          orphanRemoval = true,
          targetEntity = B.class,
          mappedBy = "id")
      @AggregateMember(eventForwardingMode = ForwardMatchingInstances.class)
      @JsonIgnoreProperties("id")
      private List<C> transactions = new ArrayList<>();
    }
    
    @Entity
    @Table(name = "B")
    @DynamicUpdate
    @Getter
    @Setter
    @NoArgsConstructor
    @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
    @Log4j2
    Class B implements Serializable {
    
      @Id
      @EntityId
      @Column(name = "id", nullable = false)
      @AggregateIdentifier
      private String id;
    
      @ManyToOne(fetch = FetchType.LAZY)
      @JoinColumns({@JoinColumn(name = "id", referencedColumnName = "id")})
      @JsonIgnoreProperties("transactions")
      private A a;
    
      @EventSourcingHandler
      public void on(final Event2 e2) {
       //some updates to the model
      }
    }

我使用的是一个状态存储聚合,但在Spring测试中使用嵌入式H2时,我总是随机地得到错误。在非嵌入式模式下,PGSQL DB不会出现同样的问题,但我们无法在流水线中运行它。

    protected <P> EventMessage<P> createMessage(P payload, MetaData metaData) {
            if (lastKnownSequence != null) {
                String type = inspector.declaredType(rootType())
                                       .orElse(rootType().getSimpleName());
                long seq = lastKnownSequence + 1;
                String id = identifierAsString();
                if (id == null) {
                    Assert.state(seq == 0,
                                 () -> "The aggregate identifier has not been set. It must be set at the latest when applying the creation event");
                    return new LazyIdentifierDomainEventMessage<>(type, seq, payload, metaData);
                }
                return new GenericDomainEventMessage<>(type, identifierAsString(), seq, payload, metaData);
            }
            return new GenericEventMessage<>(payload, metaData);
        }

这有什么解决办法?我是否遗漏了一些配置或需要修复Axon代码?

共有1个答案

云弘壮
2023-03-14

我相信您得到的异常是指向您缺少的@Rohitdev的指针。在Axon中创建聚合时,它至少假设您将设置聚合标识符。因此,您将填写聚合中存在的@aggregateIdentifier注释字段。

这是一个强制验证,因为如果没有聚合标识符,您基本上就缺少了对聚合的外部引用。因此,您只需将以下命令分派到该集合,因为没有路由它们的方法

从您共享的代码片段中,没有任何东西表明在聚合AB中设置了@aggregateIdentifier注释的字符串ID字段。如果不结合使用Axon的测试夹具来执行此操作,将导致您得到异常。

最后,您的示例仍然使用@EventSourcingHandler注释函数,当您有事件源聚合时应该使用这些函数。听起来您有意识地做出了反对事件源的决定,因此我也不会在您的模型中使用这些注释。现在,开发人员可能只会迷惑于使用状态存储聚合逻辑和事件源聚合逻辑的混合。

 类似资料:
  • null 我设置应用程序的方式是使用aggregateview将所需数据持久化到数据库中。因此,现在我感觉事件只是存储在事件存储区中,并且只在调用命令后用于重新创建聚合。对于正在存储的事件和集合的重新创建,我难道没有其他事情要做吗?例如,我是否应该重新创建整个聚合,而不是按ID从数据库中取出aggregateview来更新它。

  • 下面是一个简单的场景: 用户单击“Create order”:将创建一个订单(首先保持其状态=NEW) 用户完成订单填写后,单击SAVE-->state is now Submited 当另一个检查订单并验证它时,必须进行一个过程。只有在调用了其他一些服务并给予许可时,才会验证该订单。 整个工作流程是: null null 谢谢

  • 异常处理表示“将只处理从同一个类中的消息处理函数引发的异常” 消息拦截文档说:“用注释的函数将被视为处理程序拦截器,只有在异常结果时才会调用该函数。例如,为此目的使用注释函数允许您作为引发的数据库/服务异常的结果引发更特定于域的异常。” 但我不能让它起作用。我尝试添加异常处理程序,如下所示: 但不调用此方法。我尝试将异常处理程序方法放在聚合和单独的命令处理程序类上,尝试添加,并尝试捕获其他类型的异

  • 我有一个像下面这样的用例。对于每个传入的事件,我希望查看某个字段,看看它的状态是否从a变为B,如果是,则将其发送到输出主题。流程是这样的:一个带有键“xyz”的事件以状态A进入,一段时间后另一个带有键“xyz”的事件以状态B进入。 有没有更好的方法使用DSL来编写这个逻辑? 上面代码中关于聚合创建的状态存储的两个问题。 null 提前道谢!

  • 我有一个服务,它有一个存储库作为构造函数的参数。 是默认的Spring存储库,没有实现 我在上编写,并使用编写测试。。保留的变体是使用方面,但没有完全像我希望的那样。会非常感激你的帮助。 更新:的用法: 配置:

  • 我目前正在考虑将opengl状态存储为某种适当类型的全局thread_local变量。那个设计有多糟糕?有什么陷阱吗?