ninja icon indicating copy to clipboard operation
ninja copied to clipboard

@Transactional not working with @Schedule

Open jnye opened this issue 10 years ago • 3 comments
trafficstars

Using version 5.2.1 the following throws an exception. I've not tested earlier versions.

package services;

import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.inject.persist.Transactional;
import ninja.scheduler.Schedule;

import javax.persistence.EntityManager;
import java.util.concurrent.TimeUnit;

/*
    In Module.java:
        bind(TestScheduledAction.class);
*/
@Singleton
public class TestScheduledAction {

    @Inject
    private Provider<EntityManager> entityManagerProvider;

    @Schedule(initialDelay = 0, delay = 60, timeUnit = TimeUnit.SECONDS)
    public void run() {
        doSomething();
    }

    @Transactional
    private void doSomething() {
        if (!entityManagerProvider.get().getTransaction().isActive()) {
            throw new RuntimeException("No transaction active!");
        }
    }

}

Also, if I place @Transactional on the run method the scheduler never calls it.

jnye avatar Oct 23 '15 15:10 jnye

As a work around you can split the @Schedule class and the @Transactional class and it will work.

package services;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import ninja.scheduler.Schedule;

import java.util.concurrent.TimeUnit;

@Singleton
public class TestScheduledAction {

    @Inject
    private TestAction testAction;

    @Schedule(initialDelay = 0, delay = 60, timeUnit = TimeUnit.SECONDS)
    public void run() {
        testAction.doSomething();
    }

}
package services;

import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.inject.persist.Transactional;

import javax.persistence.EntityManager;

@Singleton
public class TestAction {

    @Inject
    private Provider<EntityManager> entityManagerProvider;

    @Transactional
    public void doSomething() {
        if (!entityManagerProvider.get().getTransaction().isActive()) {
            throw new RuntimeException("No transaction active!");
        }
    }

}

jnye avatar Oct 23 '15 16:10 jnye

I meet the same question, someone would help us?

ThinkHuang avatar Jun 28 '19 03:06 ThinkHuang

@Transactional does not work on private methods afaik.

rrarrarra avatar Jun 28 '19 05:06 rrarrarra