Spring @Transactional + AspectJ Compile Time Weaving does not work

1.6k views Asked by At

I have a bunch of methods that are marked with @Transactional annotation and then they do self-invocation and some of the methods are private, so I want to use AspectJ flavour of transaction management with Spring.

I am compiling my code with aspectj-maven-plugin version 1.11:

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.11</version>
                <configuration>
                    <proc>none</proc>
                    <forceAjcCompile>true</forceAjcCompile>
                    <complianceLevel>${java.version}</complianceLevel>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <showWeaveInfo>true</showWeaveInfo>


                    <aspectLibraries>
                        <aspectLibrary>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-aspects</artifactId>
                        </aspectLibrary>
                    </aspectLibraries>


                    <sources>
                        <source>
                            <basedir>${project.build.directory}/generated-sources/annotations</basedir>
                        </source>
                        <source>
                            <basedir>${project.build.directory}/generated-sources/delombok</basedir>
                        </source>
                    </sources>
                    <testSources>
                        <source>
                            <basedir>
                                ${project.build.directory}/generated-test-sources/delombok
                            </basedir>
                        </source>
                    </testSources>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

The compile part works fine and I see my classes being woven in the logs and I can also see that in the class files: a bunch of ...$AjcClosure... classes.

But then, my maven script is executing integration tests (which are spring boot tests) using maven surefire plugin and the tests that are meant to verify if the transaction is being rollbacked in case an exception is being thrown, are failing.

Here is my @Configuration file:

@Configuration
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
public class MyAppConfig {

// some beans not related to persistence

}

What am I missing here?

2

There are 2 answers

0
Ihor M. On BEST ANSWER

In order to configure CTW I had to configure following bean in my config:

    @Bean
    public PlatformTransactionManager txManager(DataSource dataSource) {
        DataSourceTransactionManager txManager = new DataSourceTransactionManager(dataSource);
        AnnotationTransactionAspect.aspectOf().setTransactionManager(txManager);
        return txManager;
    }

Also, my maven file evolved into:

           <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.11</version>
                <configuration>
                    <proc>none</proc>
                    <Xlint>ignore</Xlint>
                    <forceAjcCompile>true</forceAjcCompile>
                    <complianceLevel>${java.version}</complianceLevel>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <showWeaveInfo>true</showWeaveInfo>
                    <sources/>
                    <testSources/>
                    <aspectLibraries>
                        <aspectLibrary>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-aspects</artifactId>
                        </aspectLibrary>
                    </aspectLibraries>
                </configuration>
                <executions>
                    <execution>
                        <id>compile-sources</id>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                        <configuration>
                            <weaveDirectories>
                                <weaveDirectory>${project.build.outputDirectory}</weaveDirectory>
                            </weaveDirectories>
                        </configuration>
                    </execution>
                    <execution>
                        <id>compile-test-sources</id>
                        <goals>
                            <goal>test-compile</goal>
                        </goals>
                        <configuration>
                            <weaveDirectories>
                                <weaveDirectory>${project.build.testOutputDirectory}</weaveDirectory>
                            </weaveDirectories>
                        </configuration>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjtools</artifactId>
                        <version>${aspectj.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjrt</artifactId>
                        <version>${aspectj.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
3
kriegaex On

You do not need AspectJ Maven or any other type of compile-time weaving tool in order for this to work in Spring. Just use AspectJ via LTW (load-time weaving) instead.