Skip to content
Advertisement

Spring @Transactional with base and subclasses

I am confused about @Transactional annotation with base and subclasses. I have the following code with several generic subclasses derived from the base class CustomRepository<T> which implements ICustomRepository<T>. I want all the methods of the interface ICustomRepository<T> be transactional.

// class ActivityCustomRepository.java
@Repository
public class ActivityCustomRepository extends CustomRepository<Activity> {
private static final String TABLE_NAME = "activity";
public ActivityCustomRepositoryImpl(ActivityRowMapperImpl rowMapper, JdbcTemplate jdbcTemplate) {
    super(TABLE_NAME, rowMapper, jdbcTemplate);
}

// class PersonCustomRepository.java
@Repository
public class PersonCustomRepository extends CustomRepository<Person> {
private static final String TABLE_NAME = "person";
public PersonCustomRepository(PersonRowMapperImpl rowMapper, JdbcTemplate jdbcTemplate) {
    super(TABLE_NAME, rowMapper, jdbcTemplate);
}   

// CustomRepository.java
@Transactional
public class CustomRepository<T> implements ICustomRepository<T> {
    private final String tableName;
    private final RowMapper<T> rowMapper;
    private final JdbcTemplate jdbcTemplate;
    @Override
    public List<T> findAll() {
        return jdbcTemplate.batchUpdate("... ", rowMapper);
    }
}

// ICustomRepository.java
public interface ICustomRepository<T> {
     List<T> findAll();
}

Is it enough to put @Transactional just in the base class so that the call findAll() from sublasses also become transactional. Or it is better to place @Transactional on subclasses and not put it on base class?

Advertisement

Answer

I have investigated it. As @Transactional is an inhereted annotation then if we mark a base class by @Transactional then all its subclasses will be also @Transactional automatically.

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
...
}

The inhereted annotation documentation:

Indicates that an annotation type is automatically inherited. If an Inherited meta-annotation is present on an annotation type declaration, and the user queries the annotation type on a class declaration, and the class declaration has no annotation for this type, then the class’s superclass will automatically be queried for the annotation type. This process will be repeated until an annotation for this type is found, or the top of the class hierarchy (Object) is reached. If no superclass has an annotation for this type, then the query will indicate that the class in question has no such annotation. Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class.

Note also that this meta-annotation only causes annotations to be inherited from superclasses; annotations on implemented interfaces have no effect.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement