Spring state machine to manage JPA entity

Viewed 2721

I have a Task JPA @Entity which has field state - so it looks like state machine could be good abstraction to work with. The state may change by calling a REST endpoint in form like PUT /api/tasks/{id}/state. I wanted to utilize the concept of Actions, Guards as it looks like nice abstractions. I guess I need something along:

  1. In the REST endpoint create (or rather restore?) the state machine in state corresponding to the current Tasks's state and associate the JPA entity with it's context so it is available for Actions which can change the state task's state field (and others) and persist it back through Repository
  2. Send the event representing transition to new state

I assume point 1. will create the machine through builder as with @EnableStateMachineFactory you cannot really create the machine in particular state (which kind of make sense). I'm unclear how to add the entity which I probably findOne in @Repository to the state machine's context.

Would that be the right approach? Is there a sample covering this? I was pretty honest in going through the existing samples and didn't find anything similar.

2 Answers

You should first ask yourself - do you really, really need a state machine for this (I don't know your full use case). The StateMachine will introduce some(a lot?) complexity in your code.

That being said, here's a possible design:

1) Implement your standard SOA for the Entity (e.g. TaskController -> TaskService -> TaskRepository).

2) Create a Service (W), which solely purpose is to create events and send them to the SM. In that Service (W), you will have the SM factory injected and the TaskService (for loading the state of an existing Task).

4) When Request/Event is sent to TaskController, you will call the Service (W), which will do the following:

5) In the state machine config, you will have source, target and action associated with that event. The action will call the TaskService and update the JPA entity.

This design makes sense if you have complex business rules when the Entity needs to be updated and you want the possible states transitions to be deterministic (e.g. you have a pre-defined workflow or state diagram). The business rules before each state transition can be abstracted as guards and the SM can be the interface through which others are interacting (updating) with your JPA Entity.

For rehydrating state machine from JPA Entity, please see this answer.

May I suggest the tutorial at Building REST Services with Spring? If you work all the way through it, you will see how to add actions that depend on the state of the object while creating a REST-based service.

Related