Rocky Pulley
Rocky Pulley

Reputation: 23301

How do I use JpaRepository in a backend thread?

I have an interface as follows:

public interface PackageRepository extends JpaRepository<DocPackage, String> {
}

Now I'm able to use this without any problem from my REST services by using:

@Resource
PackageRepository repo;

I can make transactional calls on it with no problem.

However when I try to load this from a worker thread:

public class MyWorker implements Runnable {
    @Resource
    PackageRepository repo;

    @Transactional
    private void doSomething() {
        DocPackage pck = repo.findOne("key");
        pck.setStatus(2);
        repo.saveAndFlush(pck);
    }

    public void run() {
        //stuff
        doSomething();
        //other stuff
    }
}

new Thread(new MyWorker()).start();

I'm able to do reads on this repo just fine, but whenever I save and flush I get the exception:

javax.persistence.TransactionRequiredException: no transaction is in progress

Is there any way to get this done correctly?

Upvotes: 4

Views: 1511

Answers (2)

talex
talex

Reputation: 20455

Spring, by default, use proxies. This mean @Transaction works only when method called from outside of class.

To fix it extract you method to service. Inject your service in MyWorker and call it.

Upvotes: 3

Matias Elorriaga
Matias Elorriaga

Reputation: 9150

I think you need to add the @Transactional annotation to your method

Upvotes: 0

Related Questions