Spring Test JUnit Runner with Automatic Transaction Rollback

Is it possible to leverage the Spring Test framework with an in-memory database like HSQLDB so that integration unit tests can be configured to automatically rollback their transactions after each test case. I am not having much luck.

Will the Axon Unit of Work be able to play nicely with the Spring Framework JUnit Runner? I am currently thinking my transactional Axon Unit of Work commits outside of the transaction provided by the Spring Framework JUnit Runner.

Has anyone gotten this to work successfully?

Currently I have to recreate my in-memory database after each test run.

Thanks for any help.

Hi Nicholas,

what is exactly the problem? Are your changes persisted, even though the Unit test is transactional?
Do you have the (Spring) @Transactional annotation on your tests? Axon doesn’t commit a transaction unless it has created it. And it doesn’t create it if one is already active. I’ve used in-memory database in my tests before, and I can’t remember having seen this problem.

Cheers,

Allard

Yes I am seeing changes persisted from prior tests even though the tests are transactional. I am pretty confident I have set up the test configuration correctly but will take another look. I have wired my Transaction Manager with the datasource and Event Bus and checked my @Transactional tests are running with the Spring Test Runner.

Thanks for letting me know you think this should work. I will take another look at my setup.

I am leveraging the new JDBC Event Store but that shouldn’t matter.

Hi Nicholas,

are you using the SimpleCommandBus?
Are configuring a specific connection provider in the jdbc event store, or do you use the default?

Cheers,

Allard

I am leveraging the SimpleCommandBus and the Default Connection Provider on the JdbcEventStore through the Axon Spring Namespace. The data source is wired into Spring’s DataSourceTransactionManager. The transaction manager is then fed to the commandBus, snapshotter, eventScheduler, sagaManager, and replayCluster.

If you put a breakpoint in the persistEvent method of org.axonframework.eventstore.jdbc.DefaultEventEntryStore, do you see a connectionProvider instance that is wrapped by a SpringDataSourceConnectionProvider?

Do you stick to default connection providers, or did you configure your own? When using Spring, you’re generally best off using defaults. If you need to configure a specific data-source, just use the data-source attribute.

Hope this helps.
Cheers,

Allard

Yes I see the UnitOfWorkAwareConnectionProviderWrapper wrapped around the SpringDataSourceConnectionProvider. I am just using the data-source attribute.

I also created a non-axon based @Transactional test in the same JUnit class with the same data source and that one rolls back correctly as expected.

I am stumped for the moment.

I’ll try to reproduce it, and let you know if I find anything.

Cheers,

Allard

Hi Nicholas,

apparently, Axon commits the transaction when a unit of work is committed, even when that unit of work is not the transaction boundary. This is most likely the cause of your events being committed, even if you have a transactional test.
You can track progress of this issue in http://issues.axonframework.org/youtrack/issue/AXON-260

Cheers,

Allard

Thanks for looking into this.

Hi,

I’m running in to what seems to be the same issue on Axon 3.0.2 with Spring boot 1.5.1. Unfortunately the youtrack link posted by Allard is dead now so I can’t check the progress of the original issue. What is the status? Is there a workaround?

Kind Regards,

Jens

Hi Jens,

the issue has been resolved a long time ago. If you’re experiencing the same issue, it must be something else.

We’ve moved to Github to track issues, that’s why the original URLs broke. I’ve created a rewrite rule to make the old urls map to the youtrack issue tracker. You should be able to visit the issue.

Cheers,

Allard

Hi,

Picking this up again because I can’t find a way to make it work. I created a bare-bones Spring Boot 1.5 / Axon 3 project with a Spock test that illustrates my issue: clone https://github.com/RealNitro/spring-boot-axon-spock and run the build using ./gradlew clean build. The second spock test will fail because the aggregate already exists. What am I doing wrong? I added a JUnit test that does the exact same thing and it also fails…

Kind Regards,

Jens

Hi Jens,

your tests weren’t annotated with @Transactional. This means the command is sent without a transaction existing, causing Axon to create one for you. Axon then commits this transaction.

By annotating with @Transactional, Spring will start a transaction around the test case (Axon won’t commit it, because it didn’t create it) and roll it back when the test completes.

Cheers,

Allard

Hi Allard,

Thanks for checking. Adding the @Transactional does indeed fix the problem in my test repository. Unfortunately in my ‘real’ repository the issue remains. I have no clue what the difference in configuration is that causes this issue. The search continues. :-/

Thx,

Jens

Hi,

I found the cause of my issues. Basically this: https://stackoverflow.com/a/29734845/223055 In one of my problem tests I accessed the REST API of my application. Those REST calls were handled in a different transaction and were not rolled back.

Kind Regards,

Jens