Quantcast
Channel: Recent Questions - Stack Overflow
Viewing all articles
Browse latest Browse all 12111

@Transactional in Spring Data MongoDB (+testcontainers)

$
0
0

I am failing to get the transactions to work in my basic spring data mongodb app. I've read articles and similar questions here and nothing seems to help. The test is being run with Testcontainers, which appears to launch Mongo with a replica set, meaning transactions should normally work. I am sure that the test config works fine at least with non-transactional code (more in the github link at the end).

The domain service:

public class EntityDomainService {  private final EntityARepository repository;  private final EntityBRepository entityBRepository;  EntityDomainService(EntityARepository repository, EntityBRepository entityBRepository) {    this.repository = repository;    this.entityBRepository = entityBRepository;  }  @Transactional  public void transactionalAdd(String id1, String id2) {    repository.save(EntityA.builder().id(id1).build());    fail();    repository.save(EntityA.builder().id(id2).build());  }  private void fail() {    throw new RuntimeException();  }}

Module-specific configuration:

@Configuration@EnableMongoRepositoriesclass EntityDomainConfiguration {  @Bean  EntityDomainService domainService(      EntityARepository entityARepository, EntityBRepository entityBRepository) {    return new EntityDomainService(entityARepository, entityBRepository);  }}

"Global" Mongo config:

@Configuration@EnableMongoRepositories()@EnableTransactionManagementclass ApplicationConfiguration extends AbstractMongoClientConfiguration {  // usual stuff  @Bean  MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {    return new MongoTransactionManager(dbFactory);  }}

Test Mongo container config:

@EnableMongoRepositoriespublic class MongoDBContainerTestConfiguration {  @Bean  @ServiceConnection  public MongoDBContainer mongoDBContainer() {    return new MongoDBContainer(DockerImageName.parse("mongo:7.0")).withExposedPorts(27017);  }}

And finally, the test itself:

@Testcontainers@DataMongoTest@ContextConfiguration(classes = [MongoDBContainerTestConfiguration.class])class EntityADomainSpec extends Specification {    @Autowired EntityAMongoRepository simulationRepository    @Autowired EntityBMongoRepository plotRepository    EntityDomainService service    def setup() {        service = new EntityDomainConfiguration().domainService(simulationRepository, plotRepository)    }    def cleanup() {        simulationRepository.deleteAll()        plotRepository.deleteAll()    }    def "basic transaction test"() {        when:        service.transactionalAdd("abc", "def")        then:        thrown(RuntimeException)        !simulationRepository.existsById("abc")    }}

Entire minimal reproducible example is hosted on my github (I hope it's pruned to the minimum, but that's my first shot at this). It contains one passing test (to show validity of the config) and the actual test of the transactional behavior:https://github.com/rafalszulejko/mongotransactions

EDIT: removed a lot of code from the github-hosted example


Viewing all articles
Browse latest Browse all 12111

Trending Articles