Fix @Transactional examples regarding method visibility#27001
Conversation
|
Good catch! This has been merged into Thanks |
On second thought, that's not entirely true: it depends on the When using However, in the Spring TestContext Framework, the In light of that, I'll modify the wording in the docs accordingly. |
|
As a proof of concept, I put together the following test case which demonstrates that import javax.sql.DataSource;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAttributeSource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.transaction.support.TransactionSynchronizationManager.isActualTransactionActive;
@SpringJUnitConfig
class NonPublicTxMethods {
@Test
void test(@Autowired Service service) {
assertThat(isActualTransactionActive()).isFalse();
service.doSomething();
}
@Configuration
@EnableTransactionManagement
static class Config {
@Bean
DataSource dataSource() {
return new EmbeddedDatabaseBuilder().generateUniqueName(true).build();
}
@Bean
PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/**
* Overrides {@link ProxyTransactionManagementConfiguration#transactionAttributeSource()}.
*/
@Bean
TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource(false);
}
@Bean
Service service() {
return new Service();
}
}
@Transactional
static class Service {
void doSomething() {
assertThat(isActualTransactionActive()).isTrue();
}
}
} |
|
Good explanation! But when we use AspectJ the annotation is only applied to public methods. |
Yes, it's an unfortunate limitation of the predefined pointcuts in However, non-public methods can at least be directly annotated with |
Spring documentation "Data Access", paragraph "1.4.6. Using @Transactional" contains incorrect description of @Transactional annotation that is used on a class level and incorrect corresponding code snippets.