Reputation: 31
Am new to Spring state machine.
I have configured the states & transitions in a configuration file, using which am able to orchestrate my micro-services successfully.
Now am planning to persist the states & transitions in an external repository (MYSQL DB)
When i tried to do that using JpaStateMachineRepository, am getting SQL Exception saying state_machine doesn't exists.
So 2 questions 1. Do we have readily available scripts for creating state machine tables. 2. Is it possible to have custom tables.
Upvotes: 3
Views: 2473
Reputation: 345
This is a liquibase version of tables for Spring Statemachine
<changeSet id="00001" author="Alexander Biryukov">
<comment>Spring State Machine JPA changelog</comment>
<!-- main tables -->
<createTable tableName="action">
<column name="id" type="bigint" autoIncrement="true">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="name" type="varchar(255)"/>
<column name="spel" type="varchar(255)"/>
</createTable>
<createTable tableName="deferred_events">
<column name="jpa_repository_state_id" type="bigint">
<constraints nullable="false"/>
</column>
<column name="deferred_events" type="varchar(255)"/>
</createTable>
<createTable tableName="guard">
<column name="id" type="bigint" autoIncrement="true">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="name" type="varchar(255)"/>
<column name="spel" type="varchar(255)"/>
</createTable>
<createTable tableName="state">
<column name="id" type="bigint" autoIncrement="true">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="initial_state" type="boolean"/>
<column name="kind" type="varchar(255)"/>
<column name="machine_id" type="varchar(255)"/>
<column name="region" type="varchar(255)"/>
<column name="state" type="varchar(255)"/>
<column name="submachine_id" type="varchar(255)"/>
<column name="initial_action_id" type="bigint"/>
<column name="parent_state_id" type="bigint"/>
</createTable>
<createTable tableName="state_machine">
<column name="machine_id" type="varchar(255)">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="state" type="varchar(255)"/>
<column name="state_machine_context" type="blob"/>
</createTable>
<createTable tableName="transition">
<column name="id" type="bigint" autoIncrement="true">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="event" type="varchar(255)"/>
<column name="kind" type="varchar(255)"/>
<column name="machine_id" type="varchar(255)"/>
<column name="guard_id" type="bigint"/>
<column name="source_id" type="bigint"/>
<column name="target_id" type="bigint"/>
</createTable>
<!-- many to many binding tables -->
<createTable tableName="state_entry_actions">
<column name="jpa_repository_state_id" type="bigint">
<constraints nullable="false"/>
</column>
<column name="entry_actions_id" type="bigint">
<constraints nullable="false"/>
</column>
</createTable>
<addPrimaryKey tableName="state_entry_actions"
columnNames="jpa_repository_state_id, entry_actions_id"
constraintName="pk_state_entry_actions"/>
<createTable tableName="state_exit_actions">
<column name="jpa_repository_state_id" type="bigint">
<constraints nullable="false"/>
</column>
<column name="exit_actions_id" type="bigint">
<constraints nullable="false"/>
</column>
</createTable>
<addPrimaryKey tableName="state_exit_actions"
columnNames="jpa_repository_state_id, exit_actions_id"
constraintName="pk_exit_entry_actions"/>
<createTable tableName="state_state_actions">
<column name="jpa_repository_state_id" type="bigint">
<constraints nullable="false"/>
</column>
<column name="state_actions_id" type="bigint">
<constraints nullable="false"/>
</column>
</createTable>
<addPrimaryKey tableName="state_state_actions"
columnNames="jpa_repository_state_id, state_actions_id"
constraintName="pk_state_state_actions"/>
<createTable tableName="transition_actions">
<column name="jpa_repository_transition_id" type="bigint">
<constraints nullable="false"/>
</column>
<column name="actions_id" type="bigint">
<constraints nullable="false"/>
</column>
</createTable>
<addPrimaryKey tableName="transition_actions"
columnNames="jpa_repository_transition_id, actions_id"
constraintName="pk_transition_actions"/>
<!-- foreign keys -->
<addForeignKeyConstraint baseTableName="deferred_events"
baseColumnNames="jpa_repository_state_id"
constraintName="fk_state_deferred_events"
referencedTableName="state"
referencedColumnNames="id"/>
<addForeignKeyConstraint baseTableName="state"
baseColumnNames="initial_action_id"
constraintName="fk_state_initial_action"
referencedTableName="action"
referencedColumnNames="id"/>
<addForeignKeyConstraint baseTableName="state"
baseColumnNames="parent_state_id"
constraintName="fk_state_parent_state"
referencedTableName="state"
referencedColumnNames="id"/>
<addForeignKeyConstraint baseTableName="transition"
baseColumnNames="guard_id"
constraintName="fk_transition_guard"
referencedTableName="guard"
referencedColumnNames="id"/>
<addForeignKeyConstraint baseTableName="transition"
baseColumnNames="source_id"
constraintName="fk_transition_source"
referencedTableName="state"
referencedColumnNames="id"/>
<addForeignKeyConstraint baseTableName="transition"
baseColumnNames="target_id"
constraintName="fk_transition_target"
referencedTableName="state"
referencedColumnNames="id"/>
<addForeignKeyConstraint baseTableName="state_entry_actions"
baseColumnNames="entry_actions_id"
constraintName="fk_state_entry_actions_a"
referencedTableName="action"
referencedColumnNames="id"/>
<addForeignKeyConstraint baseTableName="state_entry_actions"
baseColumnNames="jpa_repository_state_id"
constraintName="fk_state_entry_actions_s"
referencedTableName="state"
referencedColumnNames="id"/>
<addForeignKeyConstraint baseTableName="state_exit_actions"
baseColumnNames="exit_actions_id"
constraintName="fk_state_exit_actions_a"
referencedTableName="action"
referencedColumnNames="id"/>
<addForeignKeyConstraint baseTableName="state_exit_actions"
baseColumnNames="jpa_repository_state_id"
constraintName="fk_state_exit_actions_s"
referencedTableName="state"
referencedColumnNames="id"/>
<addForeignKeyConstraint baseTableName="state_state_actions"
baseColumnNames="state_actions_id"
constraintName="fk_state_state_actions_a"
referencedTableName="action"
referencedColumnNames="id"/>
<addForeignKeyConstraint baseTableName="state_state_actions"
baseColumnNames="jpa_repository_state_id"
constraintName="fk_state_state_actions_s"
referencedTableName="state"
referencedColumnNames="id"/>
<addForeignKeyConstraint baseTableName="transition_actions"
baseColumnNames="actions_id"
constraintName="fk_transition_actions_a"
referencedTableName="action"
referencedColumnNames="id"/>
<addForeignKeyConstraint baseTableName="transition_actions"
baseColumnNames="jpa_repository_transition_id"
constraintName="fk_transition_actions_t"
referencedTableName="transition"
referencedColumnNames="id"/>
</changeSet>
or alternatively SQL version:
create sequence hibernate_sequence start with 1 increment by 1
create table action (id bigint not null, name varchar(255), spel varchar(255), primary key (id))
create table deferred_events (jpa_repository_state_id bigint not null, deferred_events varchar(255))
create table guard (id bigint not null, name varchar(255), spel varchar(255), primary key (id))
create table state (id bigint not null, initial_state boolean, kind integer, machine_id varchar(255), region varchar(255), state varchar(255), submachine_id varchar(255), initial_action_id bigint, parent_state_id bigint, primary key (id))
create table state_entry_actions (jpa_repository_state_id bigint not null, entry_actions_id bigint not null, primary key (jpa_repository_state_id, entry_actions_id))
create table state_exit_actions (jpa_repository_state_id bigint not null, exit_actions_id bigint not null, primary key (jpa_repository_state_id, exit_actions_id))
create table state_state_actions (jpa_repository_state_id bigint not null, state_actions_id bigint not null, primary key (jpa_repository_state_id, state_actions_id))
create table state_machine (machine_id varchar(255) not null, state varchar(255), state_machine_context blob, primary key (machine_id))
create table transition (id bigint not null, event varchar(255), kind integer, machine_id varchar(255), guard_id bigint, source_id bigint, target_id bigint, primary key (id))
create table transition_actions (jpa_repository_transition_id bigint not null, actions_id bigint not null, primary key (jpa_repository_transition_id, actions_id))
alter table deferred_events add constraint fk_state_deferred_events foreign key (jpa_repository_state_id) references state
alter table state add constraint fk_state_initial_action foreign key (initial_action_id) references action
alter table state add constraint fk_state_parent_state foreign key (parent_state_id) references state
alter table state_entry_actions add constraint fk_state_entry_actions_a foreign key (entry_actions_id) references action
alter table state_entry_actions add constraint fk_state_entry_actions_s foreign key (jpa_repository_state_id) references state
alter table state_exit_actions add constraint fk_state_exit_actions_a foreign key (exit_actions_id) references action
alter table state_exit_actions add constraint fk_state_exit_actions_s foreign key (jpa_repository_state_id) references state
alter table state_state_actions add constraint fk_state_state_actions_a foreign key (state_actions_id) references action
alter table state_state_actions add constraint fk_state_state_actions_s foreign key (jpa_repository_state_id) references state
alter table transition add constraint fk_transition_guard foreign key (guard_id) references guard
alter table transition add constraint fk_transition_source foreign key (source_id) references state
alter table transition add constraint fk_transition_target foreign key (target_id) references state
alter table transition_actions add constraint fk_transition_actions_a foreign key (actions_id) references action
alter table transition_actions add constraint fk_transition_actions_t foreign key (jpa_repository_transition_id) references transition
Upvotes: 3
Reputation: 31463
If you have enabled the Spring state machine JPA auto-configuration (StateMachineJpaRepositoriesAutoConfiguration
) this will enable all the default repositories and entities used for persisting states, transitions etc. in a database.
A complete list of those entities and repositories can be found here.
For example the JpaRepositoryAction
entity will create a table ACTION
, as can be seein in the entity definition (@Table(name = "Action"
).
The default db schema looks like this:
Upvotes: 1
Reputation: 167
You just need to create STATE_MACHINE table. After creation the persist feature works like charm.
Following is the mysql script for the said table.
CREATE TABLE `STATE_MACHINE`(
MACHINE_ID VARCHAR(255) NOT NULL,
STATE VARCHAR(255),
STATE_MACHINE_CONTEXT BLOB
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
Upvotes: 1
Reputation: 31
Found the solution, default JPA entities are available in State Machine libraries. Just create the tables, records can be inserted automatically as expected.
Upvotes: 0