Persisting ListMap as Aggregate attribute

Hello guys,

I am writing an Aggregate that contains a scala.immutable.Map as an attribute:

case class SchedulerState(id: String, created: String, timestamp: String, status: String,
                          timeWindowStarted: String, timeWindowSequence: Long, timeWindowDuration: String,
                          recurrentTaskExecutionCount: Int, maxRecurrentTaskExecutions: Int,
                          recurrentTasks: Map[String, Task], oneTimeTaskExecutionCount: Int,
                          maxOneTimeTaskExecutions: Int, oneTimeTasks: Map[String, Task],
                          runningTasks: Map[String, Task], version: Long, parameters: Map[String, String]) {

This map is initialized using scala.collection.immutable.ListMap.empty:


  def initial: SchedulerState = SchedulerState(id = "", parameters = Map.empty,
    created = LocalDateTime.now.toString, timestamp = LocalDateTime.now.toString, status = "notInitialized",
    timeWindowStarted = LocalDateTime.now.toString, timeWindowSequence = 0, timeWindowDuration = "PT10S",
    recurrentTaskExecutionCount = 0, maxRecurrentTaskExecutions = 2, recurrentTasks = ListMap.empty,
    oneTimeTaskExecutionCount = 0, maxOneTimeTaskExecutions = 8, oneTimeTasks = ListMap.empty,
    runningTasks = ListMap.empty, version = 0)

I need to preserve the type of ListMap because I am rotating values using “map.tail + map.head” operations. After noticing that this rotation is not being done, I have investigated and found out that after restoring state, the entity being restored with HashMap instead of ListMap instances for the Map implementation. As HashMap does not preserve order, my logic is failing and the maps are not being rotated anymore.

What is the best approach to keep the ListMap implementation after restoring state?

Thanks once again,

Guilherme Zambon,
The Zambot project.

Hello guys,

I have spent a lot of time doing researching on play JSON Reads, Writes, Format and Transformers, but my first solution is based on the Companion object’s apply method, by creating a ListMap instance from apply’s Map parameter and passing it to the actual constructor:

object SchedulerState {

  def apply(id: String, created: String, timestamp: String, status: String,
            timeWindowStarted: String, timeWindowSequence: Long, timeWindowDuration: String,
            recurrentTaskExecutionCount: Int, maxRecurrentTaskExecutions: Int,
            recurrentTasks: Map[String, Task], oneTimeTaskExecutionCount: Int,
            maxOneTimeTaskExecutions: Int, oneTimeTasks: Map[String, Task],
            runningTasks: Map[String, Task], version: Long, parameters: Map[String, String]): SchedulerState = {

    new SchedulerState(
    id, created, timestamp, status, timeWindowStarted, timeWindowSequence, timeWindowDuration,
    recurrentTaskExecutionCount, maxRecurrentTaskExecutions, ListMap(recurrentTasks.toList: _*),
    oneTimeTaskExecutionCount, maxOneTimeTaskExecutions, ListMap(oneTimeTasks.toList: _*), runningTasks, version, parameters)
  }

The only drawback I see in here is that there is no deterministic order for the Map during object marshalling from JSON, but that does not hurt my overall functionality.

Please let me know if you have a more ellegant solution.

Regards,

Guilherme Zambon
The Zambot Project