【问题标题】:Axon test fails when an aggregate field type is Set -> HashSet当聚合字段类型为 Set -> HashSet 时,Axon 测试失败
【发布时间】:2020-05-28 04:44:13
【问题描述】:

当使用Set 而不是List 来保存对象集合时,我陷入了一个奇怪的(至少对我而言)失败。

我能够在此公开repo 中重现该问题,以便我希望提供一个真实案例以帮助更好地理解。

由于某种原因,我的 hashset 的哈希表在测试生命周期中有所不同,我的意思是当命令到来时,我的 Schedules 集合会逐个应用事件,尽管值相同。

测试结果是:

org.axonframework.test.AxonAssertionError: Illegal state change detected! Property "com.acme.axonsample.axonsample.WorkDay" has different value when sourcing events.
Working aggregate value:     <WorkDay(id=workDay-for-2020-01-02, day=2020-01-02, schedules=[Schedule(id=5dca3df439881c002543876e, workDuration=PT41M, begin=2020-01-02T10:00Z, end=2020-01-02T11:00Z, workLogs=Optional[[WorkLog(start=2020-01-02T09:45Z, stop=2020-01-02T10:35Z), WorkLog(start=2020-01-02T10:54Z, stop=2020-01-02T13:00Z)]]), Schedule(id=7dca3bf439881c002543836b, workDuration=PT1H, begin=2020-01-02T12:00Z, end=2020-01-02T13:00Z, workLogs=Optional[[WorkLog(start=2020-01-02T10:54Z, stop=2020-01-02T13:00Z)]]), Schedule(id=2dca3be439871c022543836a, workDuration=PT45M, begin=2020-01-02T14:00Z, end=2020-01-02T14:45Z, workLogs=Optional[[WorkLog(start=2020-01-02T13:58Z, stop=2020-01-02T14:45Z)]])], workLogs=[WorkLog(start=2020-01-02T09:45Z, stop=2020-01-02T10:35Z), WorkLog(start=2020-01-02T10:54Z, stop=2020-01-02T13:00Z), WorkLog(start=2020-01-02T13:58Z, stop=2020-01-02T14:45Z)])>
Value after applying events: <WorkDay(id=workDay-for-2020-01-02, day=2020-01-02, schedules=[Schedule(id=7dca3bf439881c002543836b, workDuration=PT1H, begin=2020-01-02T12:00Z, end=2020-01-02T13:00Z, workLogs=Optional[[WorkLog(start=2020-01-02T10:54Z, stop=2020-01-02T13:00Z)]]), Schedule(id=2dca3be439871c022543836a, workDuration=PT45M, begin=2020-01-02T14:00Z, end=2020-01-02T14:45Z, workLogs=Optional[[WorkLog(start=2020-01-02T13:58Z, stop=2020-01-02T14:45Z)]]), Schedule(id=5dca3df439881c002543876e, workDuration=PT41M, begin=2020-01-02T10:00Z, end=2020-01-02T11:00Z, workLogs=Optional[[WorkLog(start=2020-01-02T09:45Z, stop=2020-01-02T10:35Z), WorkLog(start=2020-01-02T10:54Z, stop=2020-01-02T13:00Z)]])], workLogs=[WorkLog(start=2020-01-02T09:45Z, stop=2020-01-02T10:35Z), WorkLog(start=2020-01-02T10:54Z, stop=2020-01-02T13:00Z), WorkLog(start=2020-01-02T13:58Z, stop=2020-01-02T14:45Z)])>

我没有在文档中发现使用 Set 的任何限制,即使我遇到了失败。为了保证没有重复,设置对我很重要

【问题讨论】:

  • WorkDay 类以及其中包含的所有对象是否实现了正确的equals 方法?
  • 也许对于框架来说很重要,该集合实际上存储了最后添加的元素。也许您应该重写 Set 以便 add() 方法将旧值替换为新值。
  • @Steven 我正在使用 Lombokequalshashcode 是由这个库实现的,我还尝试了来自 IntelliJ 的 equalshashcode。当我用 equals 破解它时,通过它的值检查 Set 元素一切正常,但听起来像一个丑陋的破解。使用List 工作正常。 @yuri-nevinitsin 我相信 Axon 应该处理它而不是客户端代码
  • 框架应该可以很好地处理这个问题,但显然它没有......我检查了你的示例项目并注意到了同样的事情。我正在深入研究这一点,一旦我得出结论,就会回复你。
  • 根据@allard "测试夹具使用一种特殊的 deep-equals 方法来检查聚合状态的相等性。基本上,它检查字段的所有相等性。只要字段中的值不要覆盖 Object 的 equals() 方法,它使用字段相等性。这里的问题是 Java 的集合实现都覆盖了 equals()。它们的实现然后检查实体对象上的 equals 方法。您可以关闭此机制(在您的风险自负)通过在夹具上调用 setReportIllegalStateChange(false)。"

标签: java cqrs axon


【解决方案1】:

根据 Axon 创建者的说法,主要问题与在我的情况下使用 Lombok 生成的 hashCode 有关。

为了解决这个问题,下面的代码将按预期工作:

 @Override
 public int hashCode() {
   return Objects.hash(id);
 }

整个线程都可以阅读here

PS:。由于我想继续使用 Lombok,并且我已经与其他面临相同问题的 equalshashCode 生成器进行了测试,因此我将我的实现保留为 List 而不是 Set

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-26
    • 1970-01-01
    • 1970-01-01
    • 2020-01-01
    相关资源
    最近更新 更多