javaspringspring-bootspring-data-jpaspring-statemachine

Spring State Machine - JpaRepositoryStateMachine Not a managed type Error


I am facing a problem with the spring state machine with persist configuration while using it with the @EnableJpaRepositories DB configuration

Spring State Machine Configuration is like this: (I have two spring state machines ex: OrderMachine, UserMachine)

@Slf4j
@Configuration
@EnableStateMachineFactory(name = “ORDERMACHINE")
public class OrderMachineConfiguration extends StateMachineConfigurerAdapter<States, Events> {

    @Autowired
    @Qualifier("OrderMachinePersister")
    private StateMachineRuntimePersister<States, Events, String> stateMachineRuntimePersister;


    @Override
    public void configure(StateMachineTransitionConfigurer<States, Events> transitions) throws Exception {
        transitions
                
                .withExternal().source(States.NEW).target(States.PREORDER).event(Events.CREATE)
                .and()
                .withExternal().source(States.PREORDER).target(States.CANCELLED).event(Events.CANCELLED);
    }

    @Override
    public void configure(StateMachineStateConfigurer<States, Events> states) throws Exception {
        states
                .withStates()
                .initial(States.NEW)
                .states(EnumSet.allOf(States.class))
                .end(States.CANCELLED);
    }

    @Override
    public void configure(StateMachineConfigurationConfigurer<States, Events> config) throws Exception {
        config
                .withPersistence()
                .runtimePersister(stateMachineRuntimePersister);
    }

    @Bean(name = "OrderMachineService")
    public StateMachineService<States, Events> stateMachineServiceOrder(
             StateMachineFactory<States, Events> stateMachineFactory,
             StateMachineRuntimePersister<States, Events, String> stateMachineRuntimePersister) {
        return new DefaultStateMachineService<States, Events>(stateMachineFactory, stateMachineRuntimePersister);
    }

    @Bean(name = "OrderMachinePersister")
    public StateMachineRuntimePersister<States, Events, String> stateMachineRuntimePersisterOrder(
            JpaStateMachineRepository jpaStateMachineRepository) {
        return new JpaPersistingStateMachineInterceptor<>(jpaStateMachineRepository);
    }
}

DB Configuration:

@Slf4j
@Configuration
@ConfigurationProperties("spring.datasource")
@EnableJpaRepositories(basePackages = “”org.machine.repository", entityManagerFactoryRef = “stateMachineEntityManager”, transactionManagerRef = “stateMachineTransactionManager”)
public class StateMachineDBConfiguration  {

    @Bean
    public DataSource stateMachineDatasource() {

        Properties props = getProperties();
        return DataSourceBuilder.create()
                .url(env.getProperty(MACHINE_DATASOURCE_URL))
                .driverClassName(env.getProperty(SPRING_DATASOURCE_DRIVER_CLASS_NAME))
                .username(props.getProperty(MACHINE_DATASOURCE_USERNAME))
                .password(props.getProperty(MACHINE_DATASOURCE_PASSWORD))
                .build();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean stateMachineEntityManager() {
        return getEntityManager(stateManagerDatasource(), “org.machine.model”);
    }

    @Bean
    public PlatformTransactionManager stateMachineTransactionManager() {
        return getTransactionManager(stateMachineEntityManager());
    }

}

Dependencies :

        <dependency>
            <groupId>org.springframework.statemachine</groupId>
            <artifactId>spring-statemachine-core</artifactId>
            <version>2.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.statemachine</groupId>
            <artifactId>spring-statemachine-recipes-common</artifactId>
            <version>2.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.statemachine</groupId>
            <artifactId>spring-statemachine-data-jpa</artifactId>
            <version>2.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

But with Above configuration i am getting error

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaStateMachineRepository' defined in org.springframework.statemachine.data.jpa.JpaStateMachineRepository defined in @EnableJpaRepositories declared on StateMachineDBConfiguration: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class org.springframework.statemachine.data.jpa.JpaRepositoryStateMachine

Caused by: java.lang.IllegalArgumentException: Not a managed type: class org.springframework.statemachine.data.jpa.JpaRepositoryStateMachine

Solution

  • couple of things you may try:

    1- include this configuration to your project

    spring.datasource.main.allow-bean-definition-overriding: true
    

    2- In case you have conflict between your repositories and state machine repos, you can map the packages to be scanned

    @EntityScan(basePackages = "your.entities.package")
    @EnableJpaRepositories(basePackages = "your.repositories.package")