Data Multi Persist is an example which is an extension of two other samples Chapter 50, JPA Config and Chapter 51, Data Persist. We still keep machine configuration in a database and persist into a database but this time we also have a machine containing two orthogonal regions showing how those are persisted independently. This sample is also using embedded H2 database with a H2 Console to ease playing with a database.
This sample uses spring-statemachine-autoconfigure
which on default
auto-configures repositories and entity classes needed for JPA.
Thus only @SpringBootApplication
is needed.
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
We again create a StateMachineRuntimePersister
.
@Bean public StateMachineRuntimePersister<String, String, String> stateMachineRuntimePersister( JpaStateMachineRepository jpaStateMachineRepository) { return new JpaPersistingStateMachineInterceptor<>(jpaStateMachineRepository); }
StateMachineService
makes it easier to work with a machines.
@Bean public StateMachineService<String, String> stateMachineService( StateMachineFactory<String, String> stateMachineFactory, StateMachineRuntimePersister<String, String, String> stateMachineRuntimePersister) { return new DefaultStateMachineService<String, String>(stateMachineFactory, stateMachineRuntimePersister); }
We use data from json to import configuration.
@Bean public StateMachineJackson2RepositoryPopulatorFactoryBean jackson2RepositoryPopulatorFactoryBean() { StateMachineJackson2RepositoryPopulatorFactoryBean factoryBean = new StateMachineJackson2RepositoryPopulatorFactoryBean(); factoryBean.setResources(new Resource[] { new ClassPathResource("datajpamultipersist.json") }); return factoryBean; }
What comes for a machine config RepositoryStateMachineModelFactory
can be used as shown below.
@Configuration @EnableStateMachineFactory public static class Config extends StateMachineConfigurerAdapter<String, String> { @Autowired private StateRepository<? extends RepositoryState> stateRepository; @Autowired private TransitionRepository<? extends RepositoryTransition> transitionRepository; @Autowired private StateMachineRuntimePersister<String, String, String> stateMachineRuntimePersister; @Override public void configure(StateMachineConfigurationConfigurer<String, String> config) throws Exception { config .withPersistence() .runtimePersister(stateMachineRuntimePersister); } @Override public void configure(StateMachineModelConfigurer<String, String> model) throws Exception { model .withModel() .factory(modelFactory()); } @Bean public StateMachineModelFactory<String, String> modelFactory() { return new RepositoryStateMachineModelFactory(stateRepository, transitionRepository); } }
Let’s get into actual demo. Run the boot based sample application:
# java -jar spring-statemachine-samples-datajpamultipersist-2.1.0.RC1.jar
Accessing application via http://localhost:8080 brings up a new constructed machine with every request and you can choose to send events to a machine. Possible events and machine configuration are updated from a database with every request. We also print out all state machine contexts and current root machine.
Machine datajpamultipersist1 is simple flat machine where states S1, S2 and S3 are transitioned with events E1, E2 and E3 meaning nothing new there. However machine datajpamultipersist2 contains two regions R1 and R2 directly under root level, thus a reason why root level machine really doesn’t have a state at all but we still need that root level machine to host those regions.
Regions R1 and R2 in machine datajpamultipersist2 contains states S10, S11, S12 and S20, S21, S22 respectively and events E10, E11 and E12 are used for region R1 and events E20, E21 and E22 for region R2. Lets send events E10 and E20 to machine datajpamultipersist2 and see how things look like.
Regions have their own contexts with their own id’s and where the actual
id is postfixed with #
plus region id
. As shown below there are
different contexts in a database for regions.