英文:
Spring state machine with JPA persistence- Repository usage
问题
我正在尝试弄清楚如何轻松使用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状态机
if(stateMachine.isEmpty()) {
StateMachine<UserState, UserEvent> createdStateMachine = factory.getStateMachine(user.getId()); // Spring状态机
repository.save(createdStateMachine); // 编译错误
}
// 在这里:已准备好使用的状态机 - 如何操作?
}
谢谢您的帮助!
英文:
I am trying to figure out how to easily use spring state machine including persistence with JPA.
This is the problem I am dealing with:
Incompatible data types - factory and persistence
At a certain point in the program I would like to use the state machine which is connected to a user. There are repositories for that purpose (project spring-statemachine-data-jpa
).
At first there is a check if a state machine already exists for a player, using the repository. If not, creating a new state machine and persist it.
The problem is that I have different types of state machines. The factory creates a StateMachine<UserState, UserEvent>
, the repository returns a JpaRepositoryStateMachine
. These are not compatible to each other and for me it is not clear how to persist / create / restore the state machines.
Can you please clarify that for me?
@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?
}
Thanks for your help!
答案1
得分: 6
尝试使用SpringStateMachineService来获取状态机实例,而不是直接从存储库或工厂中显式检索。您可以使用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 void someMethod(User user) {
StateMachine<State, Event> stateMachine = stateMachineService.acquireStateMachine(user.getId(), false);
// 这里:可立即使用的状态机 - 例如调用stateMachine.start()
}
如果您进入acquireStateMachine
方法,您会看到它通过ID从存储库查询状态机,并在未找到任何内容时创建一个新状态机。
您可以使用JpaPersistingStateMachineInterceptor来在每次更改时隐式保存和更新状态机实例。
@Bean
public JpaPersistingStateMachineInterceptor<State, Event, String>
jpaPersistingStateMachineInterceptor() {
return new JpaPersistingStateMachineInterceptor(stateMachineRepository);
}
详见持久化状态机
英文:
Try to use SpringStateMachineService to get a state machine instance instead of explicitly retrieving it from repository or factory. You can use default implementation provided by Spring:
@Bean
public StateMachineService<State, Event> stateMachineService(
final StateMachineFactory<State, Event> stateMachineFactory,
final StateMachinePersist<WorkflowState, WorkflowEvent, String> stateMachinePersist) {
return new DefaultStateMachineService<>(stateMachineFactory, stateMachinePersist);
}
So, your code will look like:
@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
}
If you go inside the acquireStateMachine
method you can see that it queries state machine from repository by id and creates a new one if nothing found.
You can use JpaPersistingStateMachineInterceptor to implicitly save and update state machine instance on every change.
@Bean
public JpaPersistingStateMachineInterceptor<State, Event, String>
jpaPersistingStateMachineInterceptor() {
return new JpaPersistingStateMachineInterceptor(stateMachineRepository);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论