【发布时间】: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 我正在使用 Lombok 和
equals和hashcode是由这个库实现的,我还尝试了来自 IntelliJ 的equals和hashcode。当我用 equals 破解它时,通过它的值检查Set元素一切正常,但听起来像一个丑陋的破解。使用List工作正常。 @yuri-nevinitsin 我相信 Axon 应该处理它而不是客户端代码 -
框架应该可以很好地处理这个问题,但显然它没有......我检查了你的示例项目并注意到了同样的事情。我正在深入研究这一点,一旦我得出结论,就会回复你。
-
根据@allard "测试夹具使用一种特殊的 deep-equals 方法来检查聚合状态的相等性。基本上,它检查字段的所有相等性。只要字段中的值不要覆盖 Object 的 equals() 方法,它使用字段相等性。这里的问题是 Java 的集合实现都覆盖了 equals()。它们的实现然后检查实体对象上的 equals 方法。您可以关闭此机制(在您的风险自负)通过在夹具上调用 setReportIllegalStateChange(false)。"