Mongo Persistence not persisting UUID correctly
We have been trying to use the StateMachine with Mongo persistence, but so far is not working properly for us.
We setup the machineId as follow:
@Override
public void configure(StateMachineConfigurationConfigurer<AuthenticationStates, AuthenticationEvents> config) throws Exception {
config.withConfiguration()
.machineId("authentication-flow")
.autoStartup(true)
.withPersistence()
.runtimePersister(stateMachineRuntimePersister);
}
But when the record is being persisted we noticed that the id is the same as the machineId (both show as authentication-flow), when in fact it should be the uuid generated for that instance.
After a lot of debug we believe that there might be a bug in this line and it should pass (T)stateMachine.getUuid() instead of (T)stateMachine.getId().
This effectively means that all documents inserted have id=machineId=authentication-flow, so we end up with a single document being overriden by all instances.
Encountered the same. To fix that I've implemented custom MongoDbRepositoryStateMachinePersist. Example:
public class MongoDbRepositoryStateMachinePersist <S, E> extends RepositoryStateMachinePersist<Entity, S, E> {
private final EntityRepository entityRepository;
/**
* Instantiates a new mongodb repository state machine persist.
*
* @param EntityRepository the mongodb state machine repository
*/
public MongoDbRepositoryStateMachinePersist(EntityRepository entityRepository) {
super();
this.entityRepository = entityRepository;
}
/**
* Instantiates a new mongodb repository state machine persist.
*
* @param EntityRepository the mongodb state machine repository
* @param serialisationService the serialisation service
*/
public MongoDbRepositoryStateMachinePersist(EntityRepository entityRepository,
StateMachineSerialisationService<S, E> serialisationService) {
super(serialisationService);
this.entityRepository = entityRepository;
}
@Override
protected StateMachineRepository<Entity> getRepository() {
return entityRepository;
}
@Override
protected Entity build(StateMachineContext<S, E> context, Object contextObj, byte[] serialisedContext) {
var id = contextObj.toString();
var state = context.getState().toString();
var detonation = entityRepository.findById(id).orElse(null);
if (detonation == null) {
return new Entity(
contextObj.toString(),
state,
serialisedContext,
List.of(new StateChange(state, Instant.now())),
Instant.now(),
Instant.now().plus(90, ChronoUnit.DAYS)
);
} else {
return detonation
.setState(state)
.setStateMachineContext(serialisedContext)
.addStateHistory(new StateChange(state, Instant.now()))
;
}
}
}