I have been reviewing Scala since reviewing your tic-tac-toe example and the simple integration with Axon. Thank you for sharing that code. I am very new to Scala so the following issues may have better fixes than what I found.
I took one section my Java code and converted it to Scala. It consists of several classes: event listener, JPA entity and JPA repository. The code savings in terms of lines of code was 50.4% by using Scala.
I then converted one of my events to a Scala case class. I did not follow your example of using a Scala object (Events.scala) to hold the events as I wanted a drop-in replacement for my existing code.
The first issue I noticed was a lack of a “get” method for my attributes. That was easy to fix: getCompanyId() converts to companyId().
The second issue was a Axon saga using annotations. The associated property was defined as “companyId” but there is a private static helper method named “methodForProperty” which will convert that string to “getCompanyId” to which is passed to the Java reflection library to find the method. No such method exists of course (see the first issue). Again it was a relatively easy fix to add a function: def getCompanyId() = companyId
case class CompanyAssociationEstablishedEvent(orderId: OrderId, revisionId: RevisionId, companyId: String) extends OrderEvent(orderId) {
def getRevisionId() = revisionId
}
Only a few events are actually used in the saga lifecycle so this is a small trade off.
The third issue are events which extend a base class and the XML serialisation in the event store. The tic-tac-toe example extends an Axon v1 DomainEvent class but since I’ve moved to Axon v2 I no longer have that class. I do however have a base class for like events, ie: abstract OrderEvent. Events have changed from:
<org.example.api.events.CompanyAssociationEstablishedEvent>
44b2c875-d391-49c1-81e2-cc18d9b82d11
de4b20c7-91d8-4e5b-a217-8ba04b7e3595
ABCINC
</org.example.api.events.CompanyAssociationEstablishedEvent>
to:
<org.example.api.events.CompanyAssociationEstablishedEvent>
44b2c875-d391-49c1-81e2-cc18d9b82d11
de4b20c7-91d8-4e5b-a217-8ba04b7e3595
ABCINC
</org.example.api.events.CompanyAssociationEstablishedEvent>
The OrderEvent.java class has an attribute for orderId and the getter getOrderId() defined. The CompanyAssociationEstablishedEvent.scala, when referenced from a Java object, has two methods: companyId() and getCompanyId(). If the first event is loaded (ie: legacy) then “getCompanyId()” will return a null. I am not sure how I can pass an “orderId” to a super class without duplicating the field in my case class.
I will certainly continue to exercise Scala