Elad Tabak
Elad Tabak

Reputation: 2417

Spring ignores @Transactional annotations

Seems like spring ignores @Transactional annotations on service classes. I read a few q&a on SO and blogs but none of the options seems to work for me.

  1. I'm NOT calling a private method - I call a public method that is exposed on the interface.
  2. I'm calling a method on a different class (i.e. not calling on from the same class).
  3. My "service" class is annotated with @Component and @Transactional.
  4. My "service class has an interface, and I'm injecting it using the interface, and @Inject annotation.
  5. I tried adding proxy-target-class="true" as described here in one of the answers - didn't work.
  6. I'm using JAX-RS (not spring-mvc).

The error happens on the DAO layer, annotated with @Transactional(propagation = Propagation.MANDATORY), when I get this exception:

org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'

Here's some general code that represents the classes and interfaces involved:

public interface IService<T extends BaseEntity> {
    void save(T entity);
}

public abstract class AbstractService<T extends BaseEntity> implements IService<T> {

    @Inject
    private IDao dao;

    @Override
    public void save(T entity) {
        dao.save(entity);
    }
}

public interface IPersonService extends IService<PersonEntity> {
        void saveAll(List<PersonEntity> persons);
}

@Component
@Transactional
public class PersonService extends AbstractService<PersonEntity> implements IPersonService {

    @Override
    public void saveAll(List<PersonEntity> persons) {
        for (PersonEntity person : persons) {
            super.save(person);
        }
    }
}

@Component
public class PersonApi {

    @Inject
    private IPersonService personService;

    public void saveAll(...) {
        ...
        personService.saveAll(persons);
    }
}

Any ideas or suggestions?

Upvotes: 3

Views: 2141

Answers (1)

Elad Tabak
Elad Tabak

Reputation: 2417

So it turns out I must also annotate the abstract class with @Transactional as well, otherwise it will not work. Spring documentation talks only about interfaces. Since I'm calling an abstract class method here, it also needs to be @Transactional.

@Transactional
public abstract class AbstractService<T extends BaseEntity> implements IService<T> {

    @Inject
    private IDao dao;

    @Override
    public void save(T entity) {
        dao.save(entity);
    }


}

Upvotes: 2

Related Questions