'Micronaut, db-scheduler: No current transaction present. Consider declaring @Transactional on the surrounding method
I'm trying to use db-scheduler with Micronaut. Therefore, I created a @Singleton service where I inject the actual DataSource which is of type TransactionAwareDataSource. I then call a certain method to setup the scheduler which is something like:
  @Transactional
  public void createJob() {
    RecurringTask<Void> hourlyTask = Tasks.recurring("my-hourly-task", FixedDelay.ofHours(1))
        .execute((inst, ctx) -> {
          System.out.println("Executed!");
        });
    final Scheduler scheduler = Scheduler
        .create(dataSource)
        .startTasks(hourlyTask)
        .threads(5)
        .build();
    scheduler.start();
  }
which, at "create" throws this exception:
io.micronaut.transaction.exceptions.NoTransactionException: No current transaction present. Consider declaring @Transactional on the surrounding method
    at io.micronaut.transaction.jdbc.TransactionalConnectionInterceptor.intercept(TransactionalConnectionInterceptor.java:65)
    at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:96)
    at io.micronaut.transaction.jdbc.TransactionalConnection$Intercepted.getMetaData(Unknown Source)
    at com.github.kagkarlsson.scheduler.jdbc.AutodetectJdbcCustomization.<init>(AutodetectJdbcCustomization.java:40)
    at com.github.kagkarlsson.scheduler.SchedulerBuilder.lambda$build$0(SchedulerBuilder.java:190)
    at java.base/java.util.Optional.orElseGet(Optional.java:369)
Everywhere else in my app everything is working like it should, means, I can read and write to the DB via the repositories and @Transactional is working as well.
I'm not 100% sure where the problem is, but I guess it does have to do with placing the annotation. Which - in this case - is nothing I can really change. On the other hand, if I create the datasource manually, effectively bypassing micronaut, it's working.
BTW: the exception comes up within db-scheduler where the first call to the DB is made (c.getMetaData().getDatabaseProductName()).
Micronaut-Version: 2.3.4, Micronaut-Data: 2.2.4, everything setup properly.
Do you guys have any ideas how to solve this problem? Or is it even a bug?
Thanks!
Solution 1:[1]
So the problem is that Micronaut Data wraps the DataSource into a TransactionAwareDataSource, as you mentioned. Your library db-scheduler or mine JobRunr picks it up, and operates without the required annotations. The solution is to unwrap it before giving it to the db-scheduler or JobRunr:
Kotlin:
val unwrappedDataSource = (dataSource as DelegatingDataSource).targetDataSource
Java:
DataSource unwrappedDataSource = ((DelegatingDataSource) dataSource).targetDataSource
    					Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source | 
|---|---|
| Solution 1 | X.Y. | 
