1

I wrote a Test for a MongoRepository in Spring Boot, and the test works fine. The only problem is that when the test is over, I want a rollback, so that there will be no change in the database caused by the test.

// package...

// imports...

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MetistrafficApplication.class)
@Rollback(true)
public class AppRepositoryTests {

    @Autowired
    private AppRepository appRepository;

    @Test
    public void insertTest() {
        App app = new App("test");
        App appInserted = appRepository.save(app);

        assertThat(appInserted.getName(), equalTo(app.getName()));
    }
}

I put @Transactional before @Rollback, but get this error:

java.lang.illegalstateexception:Failed to retrieve PlatformTransactionManager for @Transactional test for test context

When I searched for the error, I couldn't find any code with MongoRepository. So, how can I solve this?

EDIT: After adding @Transactional("PlatformTransactionManager"), the error I get is changed to this:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'PlatformTransactionManager' is defined: No matching PlatformTransactionManager bean found for qualifier 'PlatformTransactionManager' - neither qualifier match nor bean name match!
kalahari
  • 895
  • 5
  • 15
  • 34

3 Answers3

3

As far as I know, there isn't an implementation of Spring's TransactionManager for MongoDB since it is not transactional in the ACID sense. So no, you cannot use @Transactional annotations with MongoDB and you'll have to do all the cleanup manually or else use DBUnit and add your own extensions for MongoDB.

EDIT: As Petter mentioned in his answer, starting with MongoDB 4.0, MongoDB has support for ACID transactions and you can find the official SpringData examples on GitHub and also have the feature's release post in Spring's developer blog

Miloš Milivojević
  • 5,219
  • 3
  • 26
  • 39
  • 1
    I guess I will accept this until a better solution shows up :( – kalahari Jul 13 '16 at 15:43
  • You can also look at [this question](https://stackoverflow.com/questions/21386449/spring-data-and-mongodb-simple-roll-back-with-spring-within-transactional), although you'll get the same answer :) – Miloš Milivojević Jul 13 '16 at 15:48
2

Now you can use @Transactional with mongo. Take a look at this example: https://www.baeldung.com/spring-data-mongodb-transactions

You'll need mongo 4.0. Also need to enable mongo replication (mongod --replSet rs0)

Then you'll need to add this bean to your spring application

@Bean
MongoTransactionManager transactionManager(MongoDbFactory dbFactory) {
    return new MongoTransactionManager(dbFactory);
}

This is enough to use @Transactional in your code.

Petter
  • 318
  • 2
  • 13
0

I guess you use try catch block. Its better if you can avoid try catch. Anyway if you need to rollback you can do it like this.

 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();