in Coding

Event Sourcing with Kotlin

Some weeks ago I published a demo project on GitHub showing a Domain Driven Design with Kotlin. You can find the original blog post right here. Now I took the approach one step further and added Event Sourcing to the demo. Here’s what I did.

Event Sourcing

The basic idea of Event Sourcing is to store a stream of events instead the current state of an object. So Event Sourcing is a different persistence approach.

Traditionally, we would store the current state of an object in a relational database. We would map the object to tables and columns and update them every time the object changes.

Event Sourcing takes a different approach. Instead of saving the object, all changes to the object are saved. In Domain Driven Design and Event Sourcing those changes are called events. The sum of all events make up the current state of the object.

The benefit of this type of persistence is that we always keep the whole history of an object. We can see each and every change which occurred over time.

The downside is a more complicated and unfamiliar programming concept:

To implement Event Sourcing all changes must be published via events. Even the smallest change to our domain model (setting some flag from true to false) must result in an event. Any data which is not part of an event will be lost.

Having those events, we must implement two functionalities: (1) First we need a business method which takes an input, does things (calculations, calls, conversions, etc.) and finally throws an event with all data involved. (2) Second we need another method which takes the event and simply applies it to the model.

The first method performs business logic and actually does something whereas the second function is just “a setter for data”. We need this differentiation, because whenever we load an object all events from the database must be applied to it. This must be done without triggering business logic and side effects.

Demo on GitHub

As this description might sound a little bit weird, I’ve prepared a small demo project on GitHub:

The demo shows a small use-case and provides a web UI which helps to see what is happening behind the scenes:


Best regards,


Leave a Reply for pufferbatterie Cancel Reply

Write a Comment


  1. Thank you for this nice demo and blog – very useful 🙂

    But some load leads to concurrency problems:

    2019-01-24 20:22:50.489 ERROR 1340 — [kExecutor-75460] .a.i.SimpleAsyncUncaughtExceptionHandler : Unexpected error occurred invoking async method ‘public void de.bringmeister.connect.product.application.product.ProductService.handle(de.bringmeister.connect.product.domain.product.UpdateMasterDataCommand)’.

    java.util.ConcurrentModificationException: null
    at java.util.ArrayList$Itr.checkForComodification( ~[na:1.8.0_151]
    at java.util.ArrayList$ ~[na:1.8.0_151]
    at de.bringmeister.connect.product.infrastructure.stubs.StubbedEventStore.allFor(StubbedEventStore.kt:32) ~[main/:na]
    at de.bringmeister.connect.product.application.product.ProductService.handle(ProductService.kt:33) ~[main/:na]
    at de.bringmeister.connect.product.application.product.ProductService$$FastClassBySpringCGLIB$$efff18da.invoke() ~[main/:na]
    at org.springframework.cglib.proxy.MethodProxy.invoke( ~[spring-core-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint( ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed( ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0( ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at ~[na:1.8.0_151]
    at ~[na:1.8.0_151]