具有 JPA 持久性的 Spring 状态机 - 存储库使用

问题描述 投票:0回答:2

我正在尝试弄清楚如何轻松使用 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?

}

感谢您的帮助!

java spring spring-boot spring-data-jpa spring-statemachine
2个回答
7
投票

尝试使用 SpringStateMachineService 获取状态机实例,而不是从存储库或工厂显式检索它。您可以使用Spring提供的default实现:

@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
方法,您可以看到它通过 id 从存储库查询状态机,如果没有找到,则创建一个新状态机。

您可以使用 JpaPersistingStateMachineInterceptor 在每次更改时隐式保存和更新状态机实例。

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

参见 持久状态机


0
投票

Para que se ejecute elinterceptor agregarlo en:

    currentStateMachine.getStateMachineAccessor()
                        .doWithAllRegions(sma -> {
                            sma.addStateMachineInterceptor(captureStateMachineInterceptor);
                            sma.addStateMachineInterceptor(jpaPersistingStateMachineInterceptor);
                            sma.resetStateMachineReactively(new DefaultStateMachineContext<>(capture.get().getState(), null, null, null));
                        });
© www.soinside.com 2019 - 2024. All rights reserved.