3

I have a SpringBoot 2 app that uses using Couchbase as a database with Spring Data Couchbase

I wnt to add a transaction manager to add the annotation @Transactional in the test to do the rollback, otherwise I get this error:

java.lang.IllegalStateException: Failed to retrieve PlatformTransactionManager for @Transactional test: [DefaultTestContext@3bf9ce3e testClass = RequestServiceIntegrationTest, testInstance = com.pxs.rqm.requestcrud.service.RequestServiceIntegrationTest@1ebcfcf1, testMethod = shouldSaveWhenDataIsOK@RequestServiceIntegrationTest, testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@16610890 testClass = RequestServiceIntegrationTest, locations = '{}', classes = '{class com.pxs.rqm.requestcrud.Application}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@971d0d8, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@564718df, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@36f0f1be, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@2145433b], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.populatedRequestContextHolder' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.resetRequestContextHolder' -> true]]

    at org.springframework.util.Assert.state(Assert.java:94)
    at org.springframework.test.context.transaction.TransactionalTestExecutionListener.beforeTestMethod(TransactionalTestExecutionListener.java:185)
Sandro Rey
  • 2,429
  • 13
  • 36
  • 80

1 Answers1

1

Although we try to support most of the Spring interface, the @Transactional interface is specific to Relational Databases.

Updates in Couchbase are atomic (all or nothing), and as the way you model data is different than relational you usually don't need transactions that often. Think about a user, for instance, all the data related to it (preferences, address, credit cards) would be stored in the same document, that is why transactions are not usually necessary in this case.

However, if you need to update multiple documents at the same time, then you might consider using the new support for transactions which is available only on the SDK 3 for now (https://www.couchbase.com/transactions)

deniswsrosa
  • 2,421
  • 1
  • 17
  • 25
  • Its not form update multiple documents, is for rollback the Unit Tests – Sandro Rey Oct 23 '19 at 15:01
  • humm.. i think the right approach for this scenario is to use repository.deleteAll() after each test or flush the bucket (https://stackoverflow.com/questions/32287600/how-to-flush-couchbase-bucket-from-java-code) – deniswsrosa Oct 23 '19 at 17:51
  • 1
    quote: "@Transactional interface is specific to Relational Databases." -1 for that. Most other key/value or document stores supports PlatformTransactionManagers. For example MongoDB and Hazelcast both have corresponding TransactionManagers. Most spring programmers are used to handle transactions over that annotation. From my point of view it's a BIG missing feature and it makes a migration from another documentstore difficult – rloeffel May 27 '21 at 06:44