【问题标题】:Automatic Persistence of Command State [Axon Framework]命令状态的自动持久性 [Axon 框架]
【发布时间】:2019-06-20 07:06:12
【问题描述】:

我正在研究 Axon 框架,但我在命令状态的自动持久性方面遇到了困难。

我查看了有关 command model repository 的文档,据我了解,如果我有正确的依赖关系,标准存储库的命令模型的状态应该是自动持久的。这种情绪也出现在我看过的另一个blog/tutorial 中(您可能需要向下滚动到存储库部分)。

问题是虽然我添加了axon-mongo 依赖项,但命令状态并没有自动保持。我尝试根据文档配置相关的存储库 bean,但它似乎也没有工作。我什至不确定是否需要这样做(根据我对文档的理解),如果您想查询命令状态,您主要会这样做。

虽然我知道我可以创建自己的存储库并自己保存实体(类似于this tutorial),但我宁愿不提供开箱即用的功能。

我错过了什么吗?

注意:我的 Mongo 设置似乎是正确的,因为我已经按照 documentation 设法将我的事件保存在 MongoDB 中。

更新

根据 Steven 的评论(以及随后的 cmets),我决定尝试实现一个状态存储的聚合,但是我发现聚合的(反)序列化存在问题。我已将我的 Aggregate 发送给 Steven,他已经确认它很简单,应该由 XStream (反)序列化。我还尝试使用 XStream 的独立实例对我的聚合进行序列化,并且它起作用了,这让我相信这更像是 Axon 问题而不是 XStream 问题。我还尝试使用 Jackson 和 java (de)serializers(因为它们是 Axon 提供的其他选项),我发现了类似的问题。我已经得出结论,这是一个 Axon 错误,我已停止尝试解决该问题。

【问题讨论】:

  • 如果您使用事件溯源,则不应将“聚合状态”视为数据库中的文件。状态以为该聚合存储的所有事件的形式存在于事件存储中。出于性能原因,每隔这么多(可配置的)事件存储一个聚合状态的“快照”,但大多数情况下不会是当前状态。命令模型存储库将读取事件存储。将要读取的数据放入查询模型中通常是一种很好的做法。

标签: java spring mongodb axon


【解决方案1】:

根据您的问题,目前尚不清楚您是否知道可以选择的可能的命令模型存储机制。 所以首先,就像@Mzzl 在他的评论中指出的那样,您可以从两个角度查看命令模型状态:

  1. 事件来源
  2. 状态存储

默认情况下,Axon Framework 将设置您的聚合,并在其后面添加 EventSourcingRepository。这意味着,如果需要聚合(例如您的命令模型)来处理新命令,则将通过检索 它已发布的所有事件流来加载聚合。 其次,它将调用聚合实现上的所有@EventSourcingHandler 注释方法来重新创建命令模型的状态。 最后,一旦作为聚合事件流的一部分的所有事件都已处理完毕,该命令将提供给 @CommandHandler 带注释的方法。

状态存储方法显然有点不同,因为这意味着您的全部聚合将存储在存储库中。

但请注意,仅通过 GenericJpaRepository 类支持状态存储方法。因此,将聚合完整地存储在 MongoDB 中并不是一种选择。 如果您正在为您的聚合寻找事件溯源方法,则事件可以源自框架涵盖的任何EventStore 实现。 这意味着您可以选择 JPA、JDBC、MongoDb 和 Axon Server 作为存储事件和检索事件流以重新创建命令模型的方法。

配置方面,有几种方法可以解决这个问题。 如果直接使用Axon提供的Configuration API,可以使用:

  1. AggregateConfigurer#defaultConfiguration(Class<A>) 用于事件源方法
  2. AggregateConfigurer#jpaMappedConfiguration(Class<A>) 用于状态存储方法

如果您的应用程序处于 Spring Boot 环境中,则在事件源和状态存储之间切换会更简单一些。 只需在您的 Aggregate 实现上添加 @Entity 注释就足以让框架注意到您要按原样存储 Aggregate。

希望这有助于了解@The__Malteser 的情况!


更新

根据 cmets,很明显,框架默认使用的 XStreamSerializer 对对象进行反序列化/序列化,无法以状态存储的方式序列化您的 Aggregate 实例。

根据您收到的异常Cannot marshal the XStream instance in action,我进行了一些搜索/挖掘。我有一种预感,XStream 默认情况下无法简单地序列化 non-static 内部类。

但是,由于我们不确定您的 Aggregate 的实现是什么,因此很难推断这是否是手头的问题。您能否在这里与我们分享您的实现,以便我们更好地推断内部类是否是问题所在?

【讨论】:

  • 嗨史蒂文,感谢您的回复,并对迟到的回复表示歉意。我知道事件源实体和状态源实体,您提到@Entity 实际上为我指明了正确的方向。我正在关注 Axon 文档中 state-stored-aggregates 的示例,但我不断收到 No Command Handler Found。如果我用@Aggregate(连同@Entity)注释似乎可以解决,但后来我得到Cannot marshal the XStream instance in action。你知道我可能会错过什么吗?
  • 为了清楚起见,我知道问题可能与我的事件的(反)序列化有关,但我不确定如何解决它,因为文档缺少一些示例。如果您有任何示例(github 项目或其他),那将是首选。谢谢。
  • 感谢@The__Malteser 的更新。用这些点更新您的问题可能也很有价值。除此之外,我会假设状态存储的聚合可以通过XStreamSerializer 序列化,因为这实际上可以序列化任何东西!您介意提供包含您得到的Cannot marshal the XStream instance in action 异常的堆栈跟踪吗?这可能指向手头的问题。
  • 嗨@Steven。我已经通过聊天向您发送了我的回复,因为评论太长了。一旦我的问题得到解决,我会更新这个帖子。
  • 我已将我的聚合发送给 Steven,他确认我的聚合足够简单,可以通过 XStream 轻松(反)序列化。我也尝试过 Java 和 Jackson 序列化,但都没有工作。我还尝试仅使用 XStream(即不是 Axon 的 XStream)序列化我的聚合,并且它已正确序列化。这让我相信这是一个轴突问题。
猜你喜欢
  • 1970-01-01
  • 2011-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-19
  • 1970-01-01
  • 2020-12-17
相关资源
最近更新 更多