Browse Source

Document client disposal using MongoDatabaseFactory.

Closes #5012
pull/5026/head
Mark Paluch 5 months ago
parent
commit
0bb302cb8e
No known key found for this signature in database
GPG Key ID: 55BC6374BAA9D973
  1. 54
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoDatabaseFactorySupport.java
  2. 12
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleMongoClientDatabaseFactory.java
  3. 63
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleReactiveMongoDatabaseFactory.java

54
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoDatabaseFactorySupport.java

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
package org.springframework.data.mongodb.core;
import org.jspecify.annotations.Nullable;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
@ -23,7 +24,6 @@ import org.springframework.data.mongodb.MongoDatabaseFactory; @@ -23,7 +24,6 @@ import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.SessionAwareMethodInterceptor;
import org.springframework.lang.Contract;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import com.mongodb.ClientSessionOptions;
import com.mongodb.WriteConcern;
@ -33,8 +33,7 @@ import com.mongodb.client.MongoDatabase; @@ -33,8 +33,7 @@ import com.mongodb.client.MongoDatabase;
/**
* Common base class for usage with both {@link com.mongodb.client.MongoClients} defining common properties such as
* database name and exception translator. <br />
* Not intended to be used directly.
* database name and exception translator. Not intended to be used directly.
*
* @author Christoph Strobl
* @author Mark Paluch
@ -126,6 +125,7 @@ public abstract class MongoDatabaseFactorySupport<C> implements MongoDatabaseFac @@ -126,6 +125,7 @@ public abstract class MongoDatabaseFactorySupport<C> implements MongoDatabaseFac
*/
protected abstract MongoDatabase doGetMongoDatabase(String dbName);
public void destroy() throws Exception {
if (mongoInstanceCreated) {
closeClient();
@ -164,15 +164,8 @@ public abstract class MongoDatabaseFactorySupport<C> implements MongoDatabaseFac @@ -164,15 +164,8 @@ public abstract class MongoDatabaseFactorySupport<C> implements MongoDatabaseFac
* @author Christoph Strobl
* @since 2.1
*/
static final class ClientSessionBoundMongoDbFactory implements MongoDatabaseFactory {
private final ClientSession session;
private final MongoDatabaseFactory delegate;
public ClientSessionBoundMongoDbFactory(ClientSession session, MongoDatabaseFactory delegate) {
this.session = session;
this.delegate = delegate;
}
record ClientSessionBoundMongoDbFactory(ClientSession session,
MongoDatabaseFactory delegate) implements MongoDatabaseFactory {
@Override
public MongoDatabase getMongoDatabase() throws DataAccessException {
@ -201,7 +194,7 @@ public abstract class MongoDatabaseFactorySupport<C> implements MongoDatabaseFac @@ -201,7 +194,7 @@ public abstract class MongoDatabaseFactorySupport<C> implements MongoDatabaseFac
@Override
public boolean isTransactionActive() {
return session != null && session.hasActiveTransaction();
return session.hasActiveTransaction();
}
private MongoDatabase proxyMongoDatabase(MongoDatabase database) {
@ -230,39 +223,6 @@ public abstract class MongoDatabaseFactorySupport<C> implements MongoDatabaseFac @@ -230,39 +223,6 @@ public abstract class MongoDatabaseFactorySupport<C> implements MongoDatabaseFac
return targetType.cast(factory.getProxy(target.getClass().getClassLoader()));
}
public ClientSession getSession() {
return this.session;
}
public MongoDatabaseFactory getDelegate() {
return this.delegate;
}
@Override
public boolean equals(@Nullable Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
ClientSessionBoundMongoDbFactory that = (ClientSessionBoundMongoDbFactory) o;
if (!ObjectUtils.nullSafeEquals(this.session, that.session)) {
return false;
}
return ObjectUtils.nullSafeEquals(this.delegate, that.delegate);
}
@Override
public int hashCode() {
int result = ObjectUtils.nullSafeHashCode(this.session);
result = 31 * result + ObjectUtils.nullSafeHashCode(this.delegate);
return result;
}
public String toString() {
return "MongoDatabaseFactorySupport.ClientSessionBoundMongoDbFactory(session=" + this.getSession() + ", delegate="
+ this.getDelegate() + ")";
}
}
}

12
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleMongoClientDatabaseFactory.java

@ -34,7 +34,8 @@ public class SimpleMongoClientDatabaseFactory extends MongoDatabaseFactorySuppor @@ -34,7 +34,8 @@ public class SimpleMongoClientDatabaseFactory extends MongoDatabaseFactorySuppor
implements DisposableBean {
/**
* Creates a new {@link SimpleMongoClientDatabaseFactory} instance for the given {@code connectionString}.
* Creates a new {@link SimpleMongoClientDatabaseFactory} instance for the given {@code connectionString}. Using this
* constructor will create a new {@link MongoClient} instance that will be closed when calling {@link #destroy()}.
*
* @param connectionString connection coordinates for a database connection. Must contain a database name and must not
* be {@literal null} or empty.
@ -45,7 +46,8 @@ public class SimpleMongoClientDatabaseFactory extends MongoDatabaseFactorySuppor @@ -45,7 +46,8 @@ public class SimpleMongoClientDatabaseFactory extends MongoDatabaseFactorySuppor
}
/**
* Creates a new {@link SimpleMongoClientDatabaseFactory} instance from the given {@link MongoClient}.
* Creates a new {@link SimpleMongoClientDatabaseFactory} instance from the given {@link MongoClient}. Using this
* constructor will create a new {@link MongoClient} instance that will be closed when calling {@link #destroy()}.
*
* @param connectionString connection coordinates for a database connection. Must contain also a database name and not
* be {@literal null}.
@ -55,7 +57,10 @@ public class SimpleMongoClientDatabaseFactory extends MongoDatabaseFactorySuppor @@ -55,7 +57,10 @@ public class SimpleMongoClientDatabaseFactory extends MongoDatabaseFactorySuppor
}
/**
* Creates a new {@link SimpleMongoClientDatabaseFactory} instance from the given {@link MongoClient}.
* Creates a new {@link SimpleMongoClientDatabaseFactory} instance from the given {@link MongoClient}. Note that the
* client will not be closed when calling {@link #destroy()} as we assume a managed client instance that we do not
* want to close on {@link #destroy()} meaning that you (or the application container) must dispose the client
* instance once it is no longer required for use.
*
* @param mongoClient must not be {@literal null}.
* @param databaseName must not be {@literal null} or empty.
@ -89,4 +94,5 @@ public class SimpleMongoClientDatabaseFactory extends MongoDatabaseFactorySuppor @@ -89,4 +94,5 @@ public class SimpleMongoClientDatabaseFactory extends MongoDatabaseFactorySuppor
protected MongoDatabase doGetMongoDatabase(String dbName) {
return getMongoClient().getDatabase(dbName);
}
}

63
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleReactiveMongoDatabaseFactory.java

@ -19,6 +19,7 @@ import reactor.core.publisher.Mono; @@ -19,6 +19,7 @@ import reactor.core.publisher.Mono;
import org.bson.codecs.configuration.CodecRegistry;
import org.jspecify.annotations.Nullable;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.dao.DataAccessException;
@ -26,7 +27,6 @@ import org.springframework.dao.support.PersistenceExceptionTranslator; @@ -26,7 +27,6 @@ import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.mongodb.ReactiveMongoDatabaseFactory;
import org.springframework.data.mongodb.SessionAwareMethodInterceptor;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import com.mongodb.ClientSessionOptions;
import com.mongodb.ConnectionString;
@ -55,7 +55,9 @@ public class SimpleReactiveMongoDatabaseFactory implements DisposableBean, React @@ -55,7 +55,9 @@ public class SimpleReactiveMongoDatabaseFactory implements DisposableBean, React
private @Nullable WriteConcern writeConcern;
/**
* Creates a new {@link SimpleReactiveMongoDatabaseFactory} instance from the given {@link ConnectionString}.
* Creates a new {@link SimpleReactiveMongoDatabaseFactory} instance from the given {@link ConnectionString}. Using
* this constructor will create a new {@link MongoClient} instance that will be closed when calling
* {@link #destroy()}.
*
* @param connectionString must not be {@literal null}.
*/
@ -64,7 +66,10 @@ public class SimpleReactiveMongoDatabaseFactory implements DisposableBean, React @@ -64,7 +66,10 @@ public class SimpleReactiveMongoDatabaseFactory implements DisposableBean, React
}
/**
* Creates a new {@link SimpleReactiveMongoDatabaseFactory} instance from the given {@link MongoClient}.
* Creates a new {@link SimpleReactiveMongoDatabaseFactory} instance from the given {@link MongoClient}. Note that the
* client will not be closed when calling {@link #destroy()} as we assume a managed client instance that we do not
* want to close on {@link #destroy()} meaning that you (or the application container) must dispose the client
* instance once it is no longer required for use.
*
* @param mongoClient must not be {@literal null}.
* @param databaseName must not be {@literal null}.
@ -163,16 +168,8 @@ public class SimpleReactiveMongoDatabaseFactory implements DisposableBean, React @@ -163,16 +168,8 @@ public class SimpleReactiveMongoDatabaseFactory implements DisposableBean, React
* @author Christoph Strobl
* @since 2.1
*/
static final class ClientSessionBoundMongoDbFactory implements ReactiveMongoDatabaseFactory {
private final ClientSession session;
private final ReactiveMongoDatabaseFactory delegate;
ClientSessionBoundMongoDbFactory(ClientSession session, ReactiveMongoDatabaseFactory delegate) {
this.session = session;
this.delegate = delegate;
}
record ClientSessionBoundMongoDbFactory(ClientSession session,
ReactiveMongoDatabaseFactory delegate) implements ReactiveMongoDatabaseFactory {
@Override
public Mono<MongoDatabase> getMongoDatabase() throws DataAccessException {
@ -206,7 +203,7 @@ public class SimpleReactiveMongoDatabaseFactory implements DisposableBean, React @@ -206,7 +203,7 @@ public class SimpleReactiveMongoDatabaseFactory implements DisposableBean, React
@Override
public boolean isTransactionActive() {
return session != null && session.hasActiveTransaction();
return session.hasActiveTransaction();
}
private MongoDatabase decorateDatabase(MongoDatabase database) {
@ -217,7 +214,8 @@ public class SimpleReactiveMongoDatabaseFactory implements DisposableBean, React @@ -217,7 +214,8 @@ public class SimpleReactiveMongoDatabaseFactory implements DisposableBean, React
return createProxyInstance(session, database, MongoDatabase.class);
}
private MongoCollection proxyCollection(com.mongodb.session.ClientSession session, MongoCollection collection) {
private MongoCollection<?> proxyCollection(com.mongodb.session.ClientSession session,
MongoCollection<?> collection) {
return createProxyInstance(session, collection, MongoCollection.class);
}
@ -234,39 +232,6 @@ public class SimpleReactiveMongoDatabaseFactory implements DisposableBean, React @@ -234,39 +232,6 @@ public class SimpleReactiveMongoDatabaseFactory implements DisposableBean, React
return targetType.cast(factory.getProxy(target.getClass().getClassLoader()));
}
public ClientSession getSession() {
return this.session;
}
public ReactiveMongoDatabaseFactory getDelegate() {
return this.delegate;
}
@Override
public boolean equals(@Nullable Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
ClientSessionBoundMongoDbFactory that = (ClientSessionBoundMongoDbFactory) o;
if (!ObjectUtils.nullSafeEquals(this.session, that.session)) {
return false;
}
return ObjectUtils.nullSafeEquals(this.delegate, that.delegate);
}
@Override
public int hashCode() {
int result = ObjectUtils.nullSafeHashCode(this.session);
result = 31 * result + ObjectUtils.nullSafeHashCode(this.delegate);
return result;
}
public String toString() {
return "SimpleReactiveMongoDatabaseFactory.ClientSessionBoundMongoDbFactory(session=" + this.getSession()
+ ", delegate=" + this.getDelegate() + ")";
}
}
}

Loading…
Cancel
Save