Я пытаюсь понять, как легко использовать конечный автомат Spring, включая постоянство с JPA. Это проблема, с которой я сталкиваюсь:

Несовместимые типы данных - фабрика и постоянство

В определенный момент в программе я хотел бы использовать конечный автомат, подключенный к пользователю. Для этого есть репозитории (проект spring-statemachine-data-jpa). Сначала выполняется проверка, существует ли уже конечный автомат для игрока, используя репозиторий. Если нет, создайте новый конечный автомат и сохраните его.

Проблема в том, что у меня разные типы конечных автоматов. Фабрика создает StateMachine<UserState, UserEvent>, репозиторий возвращает JpaRepositoryStateMachine. Они несовместимы друг с другом, и мне непонятно, как сохранять / создавать / восстанавливать конечные автоматы.

Не могли бы вы прояснить это для меня?

@Autowired
private StateMachineRepository<JpaRepositoryStateMachine> repository;

public someMethod(User user) {

Optional<JpaRepositoryStateMachine> stateMachine = repository.findById(user.getId()); // JPA state machine

if(stateMachine.isEmpty()) {
            StateMachine<UserState, UserEvent> createdStateMachine = factory.getStateMachine(user.getId()); // spring state machine
            repository.save(createdStateMachine); // compile error
        }

// here: ready-to-use statemachine - how?

}

Спасибо за вашу помощь!

2
Pille 21 Сен 2020 в 03:03

1 ответ

Лучший ответ

Попробуйте использовать SpringStateMachineService , чтобы получить экземпляр конечного автомата вместо явного извлечения его из репозитория или фабрики. Вы можете использовать default реализация, предоставленная Spring:

@Bean
public StateMachineService<State, Event> stateMachineService(
        final StateMachineFactory<State, Event> stateMachineFactory,
        final StateMachinePersist<WorkflowState, WorkflowEvent, String> stateMachinePersist) {
    return new DefaultStateMachineService<>(stateMachineFactory, stateMachinePersist);
}

Итак, ваш код будет выглядеть так:

@Autowired
private StateMachineService<State, Event> stateMachineService;

public someMethod(User user) {
StateMachine<State, Event> stateMachine = stateMachineService.acquireStateMachine(user.getId(), false);

// here: ready-to-use statemachine - call stateMachine.start() for example

}

Если вы войдете внутрь метода acquireStateMachine, вы увидите, что он запрашивает конечный автомат из репозитория по идентификатору и создает новый, если ничего не найдено.

Вы можете использовать , чтобы неявно сохранять и обновлять экземпляр конечного автомата при каждом изменении.

@Bean
public JpaPersistingStateMachineInterceptor<State, Event, String>
        jpaPersistingStateMachineInterceptor() {
    return new JpaPersistingStateMachineInterceptor(stateMachineRepository);
}

См. Постоянный конечный автомат

1
Dauren D 21 Сен 2020 в 18:49