spring state machine – manage long running processes

I need some advice for using spring state machine for long running processes. I want to design some flow. Let’s say I have next states: Start->step1->step2->step3->finish. I have a controller that can send events to the state machine for managing transitions between states. I have a StateMachinePersister. I have a converter from StateMachineContext to byte[] and back. Sounds good for my business goal. So everything should work fine.

But I have a problem? I can’t understand how to manage cases when I will decide to change the flow. I mean that if I have a Production environment where some processes persisted in “step2” state. But I am forced to change the flow. let say that I want to add a step or remove a step in the flow. I think I will have problems during state machine deserialization.

So the question is: may be spring state machine is not suitable for me, or there are some recipes how I can manage such cases?

I have an entity which I want to manage states, transitions etc.

@Table(name = "processes", indexes = @Index(columnList = "currentState"))
public class Process extends AbstractPersistable<Long> implements ContextEntity<ProcessState, ProcessEvent, Long> { // NOSONAR

    private static final long serialVersionUID = 8848887579564649636L;

    StateMachineContext<ProcessState, ProcessEvent> stateMachineContext; // NOSONAR

    ProcessState currentState;

    public void setStateMachineContext(StateMachineContext<ProcessState, ProcessEvent> stateMachineContext) {
        if (stateMachineContext == null) {
            throw new IllegalStateException("stateMachineContext can't be null");
        this.currentState = stateMachineContext.getState();
        this.stateMachineContext = stateMachineContext;

    public StateMachineContext<ProcessState, ProcessEvent> getStateMachineContext() {
        return stateMachineContext;


I have StateMachinePersist bean which is responsible for initializing stateMachineContext for particular process.

public StateMachinePersist> persist() {
return new StateMachinePersist>() {

    public StateMachineContext<ProcessState, ProcessEvent> read(
            ContextEntity<ProcessState, ProcessEvent, Serializable> process) throws Exception {
        return process.getStateMachineContext();

    public void write(StateMachineContext<ProcessState, ProcessEvent> context,
            ContextEntity<ProcessState, ProcessEvent, Serializable> process) throws Exception {


I have StateMachineAdapter which is responsible for persisting and restoring state machine

public class DefaultStateMachineAdapter<S, E, T> {

    final StateMachineFactory<S, E> stateMachineFactory;

    final StateMachinePersister<S, E, T> persister;

    public DefaultStateMachineAdapter(StateMachineFactory<S, E> stateMachineFactory, StateMachinePersister<S, E, T> persister) {
        this.stateMachineFactory = stateMachineFactory;
        this.persister = persister;

    public StateMachine<S, E> restore(T contextObject) throws Exception {
        StateMachine<S, E> stateMachine = stateMachineFactory.getStateMachine();
        return persister.restore(stateMachine, contextObject);

    public void persist(StateMachine<S, E> stateMachine, T order) throws Exception {
        persister.persist(stateMachine, order);

    public StateMachine<S, E> create() {
        StateMachine<S, E> stateMachine = stateMachineFactory.getStateMachine();
        return stateMachine;


I have StateMachineContextConverter which is responsible for serialization/deserialization of StateMachineContext. I have used Kryo for this operations.

public class StateMachineContextConverter implements AttributeConverter<StateMachineContext, byte[]> {

    public byte[] convertToDatabaseColumn(StateMachineContext attribute) {
        return serialize(attribute);

    public StateMachineContext convertToEntityAttribute(byte[] dbData) {
        return deserialize(dbData);


I have controller which is responsible to switch states

public class ProcessEventController {

    final DefaultStateMachineAdapter<ProcessState, ProcessEvent, ContextEntity<ProcessState, ProcessEvent, ? extends Serializable>> processStateMachineAdapter;

    public ProcessEventController(DefaultStateMachineAdapter<ProcessState, ProcessEvent, ContextEntity<ProcessState, ProcessEvent, ? extends Serializable>> processStateMachineAdapter) {
        this.processStateMachineAdapter = processStateMachineAdapter;

    @RequestMapping(path = "/processes/{id}/{event}", method = RequestMethod.POST)
    public HttpEntity<Void> receiveEvent(@PathVariable("id") Process process, @PathVariable("event") ProcessEvent event) throws Exception {
        StateMachine<ProcessState, ProcessEvent> stateMachine = processStateMachineAdapter.restore(process);
        if (stateMachine.sendEvent(event)) {
            processStateMachineAdapter.persist(stateMachine, process);
            return ResponseEntity.accepted().build();
        } else {
            return ResponseEntity.unprocessableEntity().build();

Obviously you can’t modify existing running machine but as you’re already working with persistence I assume you’re at least stopping machines.

Look statemachine-examples-datajpa which is using existing machine apis to store config in a DB. We have StateMachineModelFactory which pretty much allows you to store your stuff anywhere if any build-in implementation is not suitable for you. This sample will build new machine instances every time when new events are sent. i.e. you can go to a DB using build-in editor and add new transition(s) without restarting a main java process.

This gives you some flexibility but if you need to change your running code then things will get impossible.