[axonframework] Manupilating EventSourced member in an aggregate's collection fails

Hi Viswanath,

by default, the Fixture tries to verify whether you’ve applied event sourcing correctly. For example, it can detect when you have done a state change inside the command handler method. Under some circumstances, it may return false positives (reporting an error when everything is ok). The comparison is done by comparing the values of each objects fields with an Event Sourced instance of your aggregate. However, if two objects implement an equals method or the Comparable interface, the outcome of the equals or compareTo method is used. If that method returns false (or a value != 0), the test fails.

Since you’re storing fields in a Map, which does override equals, Axon uses the equals method on the map. In turn, the Map will use the equals method on the AttributeInformation object to compare equality.

Does your AttributeInformation class implement the equals method? If so, then it probably returns false where it shouldn’t, OR, you’ve really made an event sourcing mistake somewhere. In that case, check if you don’t accidentally change a field in a method that is not an @EventHandler.

You can switch off the check altogether by using fixture.setReportIllegalStateChange(false);

Cheers,

Allard

Hi Allard,

Thanks a lot for taking time to reply.

I didn’t change the state of the EventSourcedMember of my aggregate root anywhere else but in the event handler. I just didn’t implement hashCode() and equals() methods initially.

However, I went implemented them later as below and everything worked just fine :slight_smile:

@Override
public int hashCode() {
return new HashCodeBuilder().append(this.verificationCode).append(this.verificationCodeIssuedAt).append
(this.numberOfFailedAttempts).toHashCode();
}

@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final AttributeVerificationInformation other = (AttributeVerificationInformation) obj;
return new EqualsBuilder().append(this.verificationCode, other.verificationCode)
.append(this.verificationCodeIssuedAt, other.verificationCodeIssuedAt)
.append(this.numberOfFailedAttempts, other.numberOfFailedAttempts).isEquals();
}

Thank you once again for helping me to fix the problem.

Best regards
Viswanath Jayachandran

Hi Viswanath,

something not Axon related, but your hashCode method looks wrong. The hash code should never be based on mutable data. The hashCode method should always return the same value for the same instance. Failure to do so may cause the object to become lost in HashMap (when used as key), HashSet and other hash based collections.

Cheers,

Allard