Skip to content

Add GORM for MongoDB / Spring Data MongoDB interop module#15745

Open
codeconsole wants to merge 5 commits into
apache:8.0.xfrom
codeconsole:feat/mongo-spring-data-interop
Open

Add GORM for MongoDB / Spring Data MongoDB interop module#15745
codeconsole wants to merge 5 commits into
apache:8.0.xfrom
codeconsole:feat/mongo-spring-data-interop

Conversation

@codeconsole

Copy link
Copy Markdown
Contributor

Depends on #15744 (stacked PR)

This is stacked on top of #15744 (opt-in MongoDB transactions). Until #15744 merges, the diff here also includes its commit — please review/merge #15744 first, after which this PR reduces to just the new interop module. The unified transaction here relies on the ClientSession introduced by #15744.

What

A new opt-in module, grails-data-mongodb-spring-data, that lets GORM for MongoDB and Spring Data MongoDB run side by side over the same MongoClient, database and codecs — and, within a single @Transactional method, the same MongoDB transaction.

When the module and spring-data-mongodb are on the classpath of a Spring Boot app that has a GORM MongoDatastore, it auto-configures over GORM's connection:

  • a MongoDatabaseFactory bound to GORM's client + default database (it does not close GORM's client),
  • a MongoTemplate (+ MappingMongoConverter) sharing the driver codec registry,
  • a primary transactionManager (GormSharedSessionMongoTransactionManager) that binds GORM's ClientSession into Spring Data, so a GORM save() and a MongoTemplate/repository write in one @Transactional method commit or roll back together.

Unified transactions require GORM server-side transactions (grails.mongodb.transactional = true, from #15744). Spring Data repositories are enabled the usual way via @EnableMongoRepositories, on a package separate from GORM @Entity classes.

Boundary

Only the connection, codecs and (within a transaction) the ClientSession are shared; the two object-mapping models stay separate (GORM maps @Entity; Spring Data maps its own documents). Sharing the session reaches Spring Data's package-private MongoResourceHolder, so a small helper lives in package org.springframework.data.mongodb — verified against the Spring Data MongoDB 5.x line in Spring Boot 4, class-path only (not JPMS module-path). A single flat transaction (PROPAGATION_REQUIRED) is supported; REQUIRES_NEW/NESTED are not.

Tests

  • UnifiedMongoTransactionSpec — GORM + MongoTemplate commit and roll back together on one session; coexistence read; sequential transactions without session/holder leaks; a Spring Data repository over the shared connection; auto-config wiring; the shared factory does not close GORM's client.
  • GormSpringDataSessionSupportSpec — coupling smoke test that fails loudly if the Spring Data internal shape changes.

Targets 8.0.x.

GORM for MongoDB previously treated a transaction as a client-side flush
boundary: pending writes were batched and flushed on commit, but each write
auto-committed individually and nothing rolled back when a later operation failed.

This adds real server-side transactions backed by a com.mongodb.client.ClientSession.
When grails.mongodb.transactional is enabled (default false), a GORM transaction
starts a ClientSession and MongoDB transaction and every read and write for the
session runs within it, committing or aborting atomically. A new MongoTransaction
drives the commit (retrying on an UnknownTransactionCommitResult) and the abort, and
closes the session afterwards.

The feature is opt-in and degrades gracefully: a standalone topology is detected at
runtime and falls back to the legacy flush-only behavior with a one-time warning.
Identifier generation for native Long ids is intentionally left non-transactional,
mirroring the semantics of database sequences.
@borinquenkid

Copy link
Copy Markdown
Member

Hi @codeconsole,

Please keep an eye on #15678, which modifies the way the MongoRegistry is being handled. It might be worth checking your diff against those updates, as this PR is downstream from 8.0.x-hibernate7.

Introduces an optional module that lets GORM for MongoDB and Spring Data MongoDB
run side by side over the same MongoClient, database and codecs, and - within a
single transaction - the same MongoDB ClientSession.

When the module and spring-data-mongodb are on the classpath of a Spring Boot
application that has a GORM MongoDatastore, SpringDataMongoGormAutoConfiguration
registers, over GORM's existing connection: a MongoDatabaseFactory bound to GORM's
client and default database (which does not close that client), a MongoTemplate and
MappingMongoConverter sharing the driver codec registry, and a primary
transactionManager.

That manager, GormSharedSessionMongoTransactionManager, extends GORM's
DatastoreTransactionManager and binds GORM's ClientSession into Spring Data's
thread-bound resources, so a GORM save() and a MongoTemplate/repository write in one
@transactional method commit or roll back together. Unified transactions require GORM
server-side transactions (grails.mongodb.transactional = true). The two object-mapping
models stay separate; only the connection, codecs and session are shared.
@codeconsole codeconsole force-pushed the feat/mongo-spring-data-interop branch from 36e36a5 to 342579f Compare June 17, 2026 23:16

@jdaugherty jdaugherty left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whats the benefit for having Spring Data and GORM?

@codeconsole

Copy link
Copy Markdown
Contributor Author

This is for apps that already have or need both, where today the only option is two separate MongoClients with no transactional consistency between them. The module makes that coexistence correct: GORM and Spring Data share one MongoClient, database and codec registry, and — within a single @Transactional — the same MongoDB ClientSession, so a GORM save() and a MongoTemplate/repository write commit or roll back together.

Concrete cases: Spring-ecosystem libraries built on MongoTemplate/Spring Data repositories (Spring Batch, Spring Session, Spring Integration, Spring Security ACL); incremental migration in either direction without doubling connections; and reaching actively-developed Spring Data features for specific operations while keeping GORM for domain modeling.

It's opt-in — a separate module that pulls in spring-data-mongodb only when an app adds it; core stays driver-only and the mapping models stay separate.

@codeconsole

Copy link
Copy Markdown
Contributor Author

Thanks @borinquenkid — I checked #15678 against this PR's diff. It's Hibernate-only: the registry-scaling changes are all in grails-data-hibernate5/grails-data-hibernate7 (plus graphql and gradle config), with no changes to grails-data-mongodb, grails-datastore-core, or grails-datamapping-core. The only shared touchpoint is gradle/mongodb-test-config.gradle, which this PR doesn't modify, so it merges cleanly. I'll rebase onto 8.0.x and re-run the Mongo suites once #15678 lands, but there's no code overlap with the interop module here.

…tx manager

Move the Spring Boot auto-configuration registration from the non-standard
META-INF/services/spring/ location to META-INF/spring/, which is where Spring Boot's
ImportCandidates actually scans - otherwise the module never auto-configures in a real
application. Add a test that asserts the imports file is at the canonical location (and
not the old one) so the path cannot silently regress.

Also document that the unified manager is @primary (required to win over GORM's
mongoTransactionManager) and how to target the intended manager in an application that
mixes another persistence stack.
Verifies the auto-configuration through an ApplicationContextRunner so the conditions,
ordering and @ConditionalOnMissingBean back-off are actually exercised in a real context
(the existing specs only invoked the @bean methods directly): the interop beans wire when
a MongoDatastore is present, nothing activates without one, and an application-defined
mongoTemplate takes precedence. Runs offline.
@testlens-app

testlens-app Bot commented Jun 20, 2026

Copy link
Copy Markdown

🚨 TestLens detected 6 failed tests 🚨

Here is what you can do:

  1. Inspect the test failures carefully.
  2. If you are convinced that some of the tests are flaky, you can mute them below.
  3. Finally, trigger a rerun by checking the rerun checkbox.

Test Summary

CI - Groovy Joint Validation Build / build_grails > :grails-data-mongodb-core:test

Test Runs
MongoTransactionSpec > test a REQUIRES_NEW inner transaction commits independently of a rolled back outer transaction
MongoTransactionSpec > test a committed transaction persists all writes atomically
MongoTransactionSpec > test a findOneAndDelete via the MongoEntity API participates in the transaction
MongoTransactionSpec > test a rolled back transaction discards all writes on the server
MongoTransactionSpec > test read-your-writes within an active transaction
MongoTransactionSpec > test writes across multiple collections roll back together

🏷️ Commit: 5887adb
▶️ Tests: 42230 executed
⚪️ Checks: 44/44 completed

Test Failures

MongoTransactionSpec > test a REQUIRES_NEW inner transaction commits independently of a rolled back outer transaction (:grails-data-mongodb-core:test in CI - Groovy Joint Validation Build / build_grails)
com.mongodb.MongoTimeoutException: Timed out while waiting for a server that matches WritableServerSelector. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:32818, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused}}]
	at com.mongodb.internal.connection.BaseCluster.logAndThrowTimeoutException(BaseCluster.java:431)
	at com.mongodb.internal.connection.BaseCluster.lambda$selectServer$0(BaseCluster.java:166)
	at com.mongodb.internal.time.Timeout.lambda$onExistsAndExpired$16(Timeout.java:238)
	at com.mongodb.internal.time.Timeout.lambda$run$10(Timeout.java:203)
	at com.mongodb.internal.time.TimePoint.checkedCall(TimePoint.java:100)
	at com.mongodb.internal.time.Timeout.call(Timeout.java:176)
	at com.mongodb.internal.time.Timeout.run(Timeout.java:196)
	at com.mongodb.internal.time.Timeout.onExistsAndExpired(Timeout.java:235)
	at com.mongodb.internal.time.Timeout.onExpired(Timeout.java:228)
	at com.mongodb.internal.connection.BaseCluster.selectServer(BaseCluster.java:165)
	at com.mongodb.internal.connection.SingleServerCluster.selectServer(SingleServerCluster.java:47)
	at com.mongodb.internal.binding.ClusterBinding.getWriteConnectionSource(ClusterBinding.java:91)
	at com.mongodb.client.internal.ClientSessionBinding.getConnectionSource(ClientSessionBinding.java:109)
	at com.mongodb.client.internal.ClientSessionBinding.getWriteConnectionSource(ClientSessionBinding.java:102)
	at com.mongodb.internal.operation.SyncOperationHelper.withSuppliedResource(SyncOperationHelper.java:169)
	at com.mongodb.internal.operation.SyncOperationHelper.withSourceAndConnection(SyncOperationHelper.java:138)
	at com.mongodb.internal.operation.SyncOperationHelper.withConnection(SyncOperationHelper.java:117)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:73)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:48)
	at com.mongodb.client.internal.MongoClusterImpl$OperationExecutorImpl.execute(MongoClusterImpl.java:472)
	at com.mongodb.client.internal.MongoDatabaseImpl.executeDrop(MongoDatabaseImpl.java:230)
	at com.mongodb.client.internal.MongoDatabaseImpl.drop(MongoDatabaseImpl.java:220)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup_closure1(MongoTransactionSpec.groovy:55)
	at org.grails.datastore.gorm.GormStaticApi.withNewSession(GormStaticApi.groovy:1019)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.withNewSession(GormEntity.groovy:1115)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup(MongoTransactionSpec.groovy:54)
MongoTransactionSpec > test a committed transaction persists all writes atomically (:grails-data-mongodb-core:test in CI - Groovy Joint Validation Build / build_grails)
com.mongodb.MongoSocketReadException: Prematurely reached end of stream
	at com.mongodb.internal.connection.SocketStream.read(SocketStream.java:184)
	at com.mongodb.internal.connection.InternalStreamConnection.receiveResponseBuffers(InternalStreamConnection.java:942)
	at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:567)
	at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceiveInternal(InternalStreamConnection.java:494)
	at com.mongodb.internal.connection.InternalStreamConnection.lambda$sendAndReceive$1(InternalStreamConnection.java:383)
	at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:386)
	at com.mongodb.internal.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:111)
	at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:757)
	at com.mongodb.internal.connection.CommandProtocolImpl.execute(CommandProtocolImpl.java:60)
	at com.mongodb.internal.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:207)
	at com.mongodb.internal.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:112)
	at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:82)
	at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:74)
	at com.mongodb.internal.connection.DefaultServer$OperationCountTrackingConnection.command(DefaultServer.java:297)
	at com.mongodb.internal.operation.SyncOperationHelper.lambda$executeRetryableWrite$11(SyncOperationHelper.java:285)
	at com.mongodb.internal.operation.SyncOperationHelper.lambda$withSourceAndConnection$1(SyncOperationHelper.java:146)
	at com.mongodb.internal.operation.SyncOperationHelper.withSuppliedResource(SyncOperationHelper.java:177)
	at com.mongodb.internal.operation.SyncOperationHelper.lambda$withSourceAndConnection$2(SyncOperationHelper.java:142)
	at com.mongodb.internal.operation.SyncOperationHelper.withSuppliedResource(SyncOperationHelper.java:177)
	at com.mongodb.internal.operation.SyncOperationHelper.withSourceAndConnection(SyncOperationHelper.java:138)
	at com.mongodb.internal.operation.SyncOperationHelper.lambda$executeRetryableWrite$12(SyncOperationHelper.java:270)
	at com.mongodb.internal.operation.SyncOperationHelper.lambda$decorateWriteWithRetries$13(SyncOperationHelper.java:329)
	at com.mongodb.internal.async.function.RetryingSyncSupplier.get(RetryingSyncSupplier.java:67)
	at com.mongodb.internal.operation.SyncOperationHelper.executeRetryableWrite(SyncOperationHelper.java:297)
	at com.mongodb.internal.operation.BaseFindAndModifyOperation.execute(BaseFindAndModifyOperation.java:81)
	at com.mongodb.client.internal.MongoClusterImpl$OperationExecutorImpl.execute(MongoClusterImpl.java:472)
	at com.mongodb.client.internal.MongoCollectionImpl.executeFindOneAndUpdate(MongoCollectionImpl.java:787)
	at com.mongodb.client.internal.MongoCollectionImpl.findOneAndUpdate(MongoCollectionImpl.java:766)
	at org.grails.datastore.mapping.mongo.engine.MongoCodecEntityPersister.generateIdentifier(MongoCodecEntityPersister.groovy:443)
	at org.grails.datastore.mapping.mongo.engine.MongoCodecEntityPersister.persistEntity(MongoCodecEntityPersister.groovy:226)
	at org.grails.datastore.mapping.mongo.engine.MongoCodecEntityPersister.persistEntity(MongoCodecEntityPersister.groovy:567)
	at org.grails.datastore.mapping.engine.EntityPersister.persist(EntityPersister.java:188)
	at org.grails.datastore.mapping.core.AbstractSession.persist(AbstractSession.java:609)
	at org.grails.datastore.gorm.GormInstanceApi.doSave(GormInstanceApi.groovy:369)
	at org.grails.datastore.gorm.GormInstanceApi.save_closure5(GormInstanceApi.groovy:184)
	at org.grails.datastore.mapping.core.DatastoreUtils.execute(DatastoreUtils.java:335)
	at org.grails.datastore.gorm.AbstractDatastoreApi.execute(AbstractDatastoreApi.groovy:44)
	at org.grails.datastore.gorm.GormInstanceApi.save(GormInstanceApi.groovy:183)
	at org.grails.datastore.gorm.GormInstanceApi.save(GormInstanceApi.groovy:123)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.save(GormEntity.groovy:110)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.test a committed transaction persists all writes atomically_closure2(MongoTransactionSpec.groovy:69)
	at grails.gorm.transactions.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:98)
	at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:137)
	at grails.gorm.transactions.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:95)
	at org.grails.datastore.gorm.GormStaticApi.withTransaction(GormStaticApi.groovy:1009)
	at org.grails.datastore.gorm.GormStaticApi.withTransaction(GormStaticApi.groovy:872)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.withTransaction(GormEntity.groovy:1024)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.test a committed transaction persists all writes atomically(MongoTransactionSpec.groovy:67)
MongoTransactionSpec > test a findOneAndDelete via the MongoEntity API participates in the transaction (:grails-data-mongodb-core:test in CI - Groovy Joint Validation Build / build_grails)
com.mongodb.MongoTimeoutException: Timed out while waiting for a server that matches WritableServerSelector. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:32818, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused}}]
	at com.mongodb.internal.connection.BaseCluster.logAndThrowTimeoutException(BaseCluster.java:431)
	at com.mongodb.internal.connection.BaseCluster.lambda$selectServer$0(BaseCluster.java:166)
	at com.mongodb.internal.time.Timeout.lambda$onExistsAndExpired$16(Timeout.java:238)
	at com.mongodb.internal.time.Timeout.lambda$run$10(Timeout.java:203)
	at com.mongodb.internal.time.TimePoint.checkedCall(TimePoint.java:100)
	at com.mongodb.internal.time.Timeout.call(Timeout.java:176)
	at com.mongodb.internal.time.Timeout.run(Timeout.java:196)
	at com.mongodb.internal.time.Timeout.onExistsAndExpired(Timeout.java:235)
	at com.mongodb.internal.time.Timeout.onExpired(Timeout.java:228)
	at com.mongodb.internal.connection.BaseCluster.selectServer(BaseCluster.java:165)
	at com.mongodb.internal.connection.SingleServerCluster.selectServer(SingleServerCluster.java:47)
	at com.mongodb.internal.binding.ClusterBinding.getWriteConnectionSource(ClusterBinding.java:91)
	at com.mongodb.client.internal.ClientSessionBinding.getConnectionSource(ClientSessionBinding.java:109)
	at com.mongodb.client.internal.ClientSessionBinding.getWriteConnectionSource(ClientSessionBinding.java:102)
	at com.mongodb.internal.operation.SyncOperationHelper.withSuppliedResource(SyncOperationHelper.java:169)
	at com.mongodb.internal.operation.SyncOperationHelper.withSourceAndConnection(SyncOperationHelper.java:138)
	at com.mongodb.internal.operation.SyncOperationHelper.withConnection(SyncOperationHelper.java:117)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:73)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:48)
	at com.mongodb.client.internal.MongoClusterImpl$OperationExecutorImpl.execute(MongoClusterImpl.java:472)
	at com.mongodb.client.internal.MongoDatabaseImpl.executeDrop(MongoDatabaseImpl.java:230)
	at com.mongodb.client.internal.MongoDatabaseImpl.drop(MongoDatabaseImpl.java:220)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup_closure1(MongoTransactionSpec.groovy:55)
	at org.grails.datastore.gorm.GormStaticApi.withNewSession(GormStaticApi.groovy:1019)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.withNewSession(GormEntity.groovy:1115)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup(MongoTransactionSpec.groovy:54)
MongoTransactionSpec > test a rolled back transaction discards all writes on the server (:grails-data-mongodb-core:test in CI - Groovy Joint Validation Build / build_grails)
com.mongodb.MongoTimeoutException: Timed out while waiting for a server that matches WritableServerSelector. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:32818, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused}}]
	at com.mongodb.internal.connection.BaseCluster.logAndThrowTimeoutException(BaseCluster.java:431)
	at com.mongodb.internal.connection.BaseCluster.lambda$selectServer$0(BaseCluster.java:166)
	at com.mongodb.internal.time.Timeout.lambda$onExistsAndExpired$16(Timeout.java:238)
	at com.mongodb.internal.time.Timeout.lambda$run$10(Timeout.java:203)
	at com.mongodb.internal.time.TimePoint.checkedCall(TimePoint.java:100)
	at com.mongodb.internal.time.Timeout.call(Timeout.java:176)
	at com.mongodb.internal.time.Timeout.run(Timeout.java:196)
	at com.mongodb.internal.time.Timeout.onExistsAndExpired(Timeout.java:235)
	at com.mongodb.internal.time.Timeout.onExpired(Timeout.java:228)
	at com.mongodb.internal.connection.BaseCluster.selectServer(BaseCluster.java:165)
	at com.mongodb.internal.connection.SingleServerCluster.selectServer(SingleServerCluster.java:47)
	at com.mongodb.internal.binding.ClusterBinding.getWriteConnectionSource(ClusterBinding.java:91)
	at com.mongodb.client.internal.ClientSessionBinding.getConnectionSource(ClientSessionBinding.java:109)
	at com.mongodb.client.internal.ClientSessionBinding.getWriteConnectionSource(ClientSessionBinding.java:102)
	at com.mongodb.internal.operation.SyncOperationHelper.withSuppliedResource(SyncOperationHelper.java:169)
	at com.mongodb.internal.operation.SyncOperationHelper.withSourceAndConnection(SyncOperationHelper.java:138)
	at com.mongodb.internal.operation.SyncOperationHelper.withConnection(SyncOperationHelper.java:117)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:73)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:48)
	at com.mongodb.client.internal.MongoClusterImpl$OperationExecutorImpl.execute(MongoClusterImpl.java:472)
	at com.mongodb.client.internal.MongoDatabaseImpl.executeDrop(MongoDatabaseImpl.java:230)
	at com.mongodb.client.internal.MongoDatabaseImpl.drop(MongoDatabaseImpl.java:220)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup_closure1(MongoTransactionSpec.groovy:55)
	at org.grails.datastore.gorm.GormStaticApi.withNewSession(GormStaticApi.groovy:1019)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.withNewSession(GormEntity.groovy:1115)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup(MongoTransactionSpec.groovy:54)
MongoTransactionSpec > test read-your-writes within an active transaction (:grails-data-mongodb-core:test in CI - Groovy Joint Validation Build / build_grails)
com.mongodb.MongoTimeoutException: Timed out while waiting for a server that matches WritableServerSelector. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:32818, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused}}]
	at com.mongodb.internal.connection.BaseCluster.logAndThrowTimeoutException(BaseCluster.java:431)
	at com.mongodb.internal.connection.BaseCluster.lambda$selectServer$0(BaseCluster.java:166)
	at com.mongodb.internal.time.Timeout.lambda$onExistsAndExpired$16(Timeout.java:238)
	at com.mongodb.internal.time.Timeout.lambda$run$10(Timeout.java:203)
	at com.mongodb.internal.time.TimePoint.checkedCall(TimePoint.java:100)
	at com.mongodb.internal.time.Timeout.call(Timeout.java:176)
	at com.mongodb.internal.time.Timeout.run(Timeout.java:196)
	at com.mongodb.internal.time.Timeout.onExistsAndExpired(Timeout.java:235)
	at com.mongodb.internal.time.Timeout.onExpired(Timeout.java:228)
	at com.mongodb.internal.connection.BaseCluster.selectServer(BaseCluster.java:165)
	at com.mongodb.internal.connection.SingleServerCluster.selectServer(SingleServerCluster.java:47)
	at com.mongodb.internal.binding.ClusterBinding.getWriteConnectionSource(ClusterBinding.java:91)
	at com.mongodb.client.internal.ClientSessionBinding.getConnectionSource(ClientSessionBinding.java:109)
	at com.mongodb.client.internal.ClientSessionBinding.getWriteConnectionSource(ClientSessionBinding.java:102)
	at com.mongodb.internal.operation.SyncOperationHelper.withSuppliedResource(SyncOperationHelper.java:169)
	at com.mongodb.internal.operation.SyncOperationHelper.withSourceAndConnection(SyncOperationHelper.java:138)
	at com.mongodb.internal.operation.SyncOperationHelper.withConnection(SyncOperationHelper.java:117)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:73)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:48)
	at com.mongodb.client.internal.MongoClusterImpl$OperationExecutorImpl.execute(MongoClusterImpl.java:472)
	at com.mongodb.client.internal.MongoDatabaseImpl.executeDrop(MongoDatabaseImpl.java:230)
	at com.mongodb.client.internal.MongoDatabaseImpl.drop(MongoDatabaseImpl.java:220)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup_closure1(MongoTransactionSpec.groovy:55)
	at org.grails.datastore.gorm.GormStaticApi.withNewSession(GormStaticApi.groovy:1019)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.withNewSession(GormEntity.groovy:1115)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup(MongoTransactionSpec.groovy:54)
MongoTransactionSpec > test writes across multiple collections roll back together (:grails-data-mongodb-core:test in CI - Groovy Joint Validation Build / build_grails)
com.mongodb.MongoTimeoutException: Timed out while waiting for a server that matches WritableServerSelector. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:32818, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused}}]
	at com.mongodb.internal.connection.BaseCluster.logAndThrowTimeoutException(BaseCluster.java:431)
	at com.mongodb.internal.connection.BaseCluster.lambda$selectServer$0(BaseCluster.java:166)
	at com.mongodb.internal.time.Timeout.lambda$onExistsAndExpired$16(Timeout.java:238)
	at com.mongodb.internal.time.Timeout.lambda$run$10(Timeout.java:203)
	at com.mongodb.internal.time.TimePoint.checkedCall(TimePoint.java:100)
	at com.mongodb.internal.time.Timeout.call(Timeout.java:176)
	at com.mongodb.internal.time.Timeout.run(Timeout.java:196)
	at com.mongodb.internal.time.Timeout.onExistsAndExpired(Timeout.java:235)
	at com.mongodb.internal.time.Timeout.onExpired(Timeout.java:228)
	at com.mongodb.internal.connection.BaseCluster.selectServer(BaseCluster.java:165)
	at com.mongodb.internal.connection.SingleServerCluster.selectServer(SingleServerCluster.java:47)
	at com.mongodb.internal.binding.ClusterBinding.getWriteConnectionSource(ClusterBinding.java:91)
	at com.mongodb.client.internal.ClientSessionBinding.getConnectionSource(ClientSessionBinding.java:109)
	at com.mongodb.client.internal.ClientSessionBinding.getWriteConnectionSource(ClientSessionBinding.java:102)
	at com.mongodb.internal.operation.SyncOperationHelper.withSuppliedResource(SyncOperationHelper.java:169)
	at com.mongodb.internal.operation.SyncOperationHelper.withSourceAndConnection(SyncOperationHelper.java:138)
	at com.mongodb.internal.operation.SyncOperationHelper.withConnection(SyncOperationHelper.java:117)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:73)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:48)
	at com.mongodb.client.internal.MongoClusterImpl$OperationExecutorImpl.execute(MongoClusterImpl.java:472)
	at com.mongodb.client.internal.MongoDatabaseImpl.executeDrop(MongoDatabaseImpl.java:230)
	at com.mongodb.client.internal.MongoDatabaseImpl.drop(MongoDatabaseImpl.java:220)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup_closure1(MongoTransactionSpec.groovy:55)
	at org.grails.datastore.gorm.GormStaticApi.withNewSession(GormStaticApi.groovy:1019)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.withNewSession(GormEntity.groovy:1115)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup(MongoTransactionSpec.groovy:54)

Muted Tests

Select tests to mute in this pull request:

  • MongoTransactionSpec > test a REQUIRES_NEW inner transaction commits independently of a rolled back outer transaction
  • MongoTransactionSpec > test a committed transaction persists all writes atomically
  • MongoTransactionSpec > test a findOneAndDelete via the MongoEntity API participates in the transaction
  • MongoTransactionSpec > test a rolled back transaction discards all writes on the server
  • MongoTransactionSpec > test read-your-writes within an active transaction
  • MongoTransactionSpec > test writes across multiple collections roll back together

Reuse successful test results:

  • ♻️ Only rerun the tests that failed or were muted before

Click the checkbox to trigger a rerun:

  • Rerun jobs

Learn more about TestLens at testlens.app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants