TransactionRequiredException and Spring Data

This post is about a recent problem I ran into using custom update queries in an application using Spring Data. I’ve had success with this in the past but this time I was trying to call the repository method directly from a lambda passed in a Spring Integration flow definition like so:

IntegrationFlows.from("myChannel")
  ...
  .handle(Integer.class, (p, h) -> {
      myEntityRepository.setSuccessForEntity(p);
      return p;
   })
   ...

The Problem

In the application I was using @Query to specify a custom update statement in the repository.

@Repository
public interface MyEntityRepository extends CrudRepository<MyEntity, Integer>{

    @Modifying
    @Query("update MyEntity e set e.status = 1 where e.parentId = ?1")
    int setSuccessForEntity(int parentId);
}

Trying to use this method resulted in:

org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query

It appears that calling the repository as I was from the lambda was not properly starting a transaction. My first attempt to fix was to add @Transactional to the repository method. This gave the same exception. Without actually digging too deep into it my guess is that the transactional behavior was getting lost in some double proxying somewhere during the creation/invocation of the repository implementation.

The Fix

To get around this problem I ended up creating a new service class to wrap the repository and annotated the service methods as @Transactional.

@Component
public class MyEntityService {

    @Autowired
    private MyEntityRepository myEntityRepository;

    @Transactional
    public void markSuccess(int parentId){
        myEntityRepository.setSuccessForEntity(parentId);
    }
}

I now use this service in my service activator instead of the repository directly.

Advertisement

3 thoughts on “TransactionRequiredException and Spring Data

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s