具有JPA持久性的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?

}

感谢您的帮助!

解决方法

尝试使用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);
}

请参见Persisting State Machine

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...