FAQ
On this page
- General
- Why are there two types of
MongoClient
in the Java driver? - Which type of
MongoClient
should I use? - How do I use the
MongoClientSettings
class? - How do I fix: "javax.net.ssl.SSLHandshakeException: extension (5) should not be presented in certificate_request"?
- How Does Connection Pooling Work in the Java Driver?
- How do I prevent the "java.lang.NoClassDefFoundError: com/mongodb/MongoClient" error?
- How do I prevent the "com.mongodb.MongoSecurityException" error?
- How do I prevent the "IllegalArgumentException: Invalid BSON field name" error?
- How do I prevent the "IllegalStateException: state should be: open" error?
- POJOs
- Do I have to specify an ID field value myself?
- Can the ID field be a compound key?
- Can I use polymorphism in a POJO accessor?
- What is a discriminator?
- Can I control serialization of
LocalDate
? - Can I serialize a
java.util.Date
as a string in format yyyy-mm-dd? - Can I make POJOs read/write directly to the field and not use the getters/setters at all?
- Can I mix private, protected, and public setters and getters?
- How do I fix: "org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class X."?
- How do I specify the collection name for a particular POJO class? Is there an annotation?
- Legacy API
- How do I connect to my MongoDB instance with the legacy API?
- How do I use the legacy
MongoClientOptions
andMongoClientURI
Classes? - Support
General
Why are there two types of MongoClient
in the Java driver?
There are two types of MongoClient
because we wanted a cleaner API
for new users that didn't have the confusion of including multiple CRUD
APIs. We wanted to ensure that the new CRUD API was available in a Java
package structure that would work well with Java module support
introduced in Java 9.
Which type of MongoClient
should I use?
New applications should generally use the
com.mongodb.client.MongoClient
interface, which supports:
Configuration with
MongoClientSettings
andConnectionString
. You can create instances of this interface via factory methods defined in thecom.mongodb.client.MongoClients
class.CRUD API using
MongoDatabase
, and from there,MongoCollection
You should use the com.mongodb.MongoClient
class if you require support for the legacy API, which supports:
Configuration with
MongoClientOptions
andMongoClientURI
CRUD API using
DB
, and from there,DBCollection
. You can access this API via thegetDB()
method.
For applications that require a mix of the new and legacy APIs, com.mongodb.MongoClient
also supports:
Configuration with
MongoClientSettings
andConnectionString
, the only difference being that you create instances via constructors instead of a factory class.CRUD API using
MongoDatabase
, and from there,MongoCollection
. You can access this API via thegetDatabase()
method.
How do I use the MongoClientSettings
class?
You can use the MongoClientSettings
class to specify configurations for
MongoClient
instances. To construct MongoClientSettings
instances, use the
MongoClientSettings.Builder
class.
Here are the sections of our documentation that show how to perform different
tasks with the MongoClientSettings
class:
For more information on the MongoClientSettings
class, see the
API Documentation for MongoClientSettings.
How do I fix: "javax.net.ssl.SSLHandshakeException: extension (5) should not be presented in certificate_request"?
This is a known error that can occur when using the TLS 1.3 protocol with specific versions of the JDK. If you encounter this error when connecting to your MongoDB instance or cluster, update your JDK to one of the following patch versions or newer:
JDK 11.0.7
JDK 13.0.3
JDK 14.0.2
How Does Connection Pooling Work in the Java Driver?
Every MongoClient
instance has a built-in connection pool for each server
in your MongoDB topology. Connection pools open sockets on demand to
support concurrent MongoDB operations in your multithreaded application.
The maximum size of each connection pool is set by the maxPoolSize
option, which
defaults to 100
. If the number of in-use connections to a server reaches
the value of maxPoolSize
, the next request to that server will wait
until a connection becomes available.
Each MongoClient
instance opens two additional sockets per server in your
MongoDB topology for monitoring the server's state.
For example, a client connected to a 3-node replica set opens 6
monitoring sockets. It also opens as many sockets as needed to support
an application's threads on each server, up to
the value of maxPoolSize
. If maxPoolSize
is 100
and the
application only uses the primary (the default), then only the primary
connection pool grows and there can be at most 106
total connections. If the
application uses a read preference to query the
secondary nodes, their pools also grow and there can be 306
total connections.
Additionally, connection pools are rate-limited such that each connection pool
can only create, at maximum, the value of maxConnecting
connections
in parallel at any time. Any additional thread stops waiting in the
following cases:
One of the existing threads finishes creating a connection, or an existing connection is checked back into the pool.
The driver's ability to reuse existing connections improves due to rate-limits on connection creation.
You can set the minimum number of concurrent connections to
each server with the minPoolSize
option, which defaults to 0
.
The connection pool will be initialized with this number of sockets. If
sockets are closed due to any network errors, causing the total number
of sockets (both in use and idle) to drop below the minimum, more
sockets are opened until the minimum is reached.
You can set the maximum number of milliseconds that a connection can
remain idle in the pool before being removed and replaced with
the maxIdleTimeMS
option, which defaults to 0
(no limit).
The following default configuration for a MongoClient
works for most
applications:
MongoClient client = new MongoClient("<connection string>")
Create a client once for each process, and reuse it for all operations. It is a common mistake to create a new client for each request, which is very inefficient.
To support high numbers of concurrent MongoDB operations
within one process, you can increase maxPoolSize
. Once the pool
reaches its maximum size, additional threads wait for sockets
to become available.
The driver does not limit the number of threads that
can wait for sockets to become available and it is the application's
responsibility to limit the size of its pool to bound queuing
during a load spike. Threads wait for the amount of time specified in
the waitQueueTimeoutMS
option, which defaults to 120000
, or 120 seconds.
A thread that waits more than the length of time defined by
waitQueueTimeoutMS
for a socket raises a connection error. Use this
option if it is more important to bound the duration of operations
during a load spike than it is to complete every operation.
When MongoClient.close()
is called by any thread, the driver
closes all idle sockets and closes all sockets that are in
use as they are returned to the pool.
How do I prevent the "java.lang.NoClassDefFoundError: com/mongodb/MongoClient" error?
You may encounter a java.lang.NoClassDefFoundError
exception when your
Java runtime environment cannot locate a class file at runtime. When you
attempt to run application code that uses the MongoDB Java Driver, you must include
the appropriate driver JAR files on the classpath.
If you receive this error after adding the Java Driver JAR files to your classpath, check the following items in your environment:
The JAR files exist in the locations specified by the classpath.
The classpath syntax is correct.
If you define the classpath in an environment variable, the Java runtime environment uses that variable.
If you use a dependency manager, it does not report any unresolvable conflicts.
Tip
This error contains the package and class name, which can help you identify which driver JAR may be missing from your classpath. To locate the driver JAR that the error refers to, check each of the entries in the API documentation.
How do I prevent the "com.mongodb.MongoSecurityException" error?
Your application might throw this exception if you specify invalid or incorrectly formatted credentials when connecting to a MongoDB deployment.
If you receive this error when you attempt to connect to a MongoDB deployment, check the following items in your code:
The connection URI corresponds to the correct MongoDB deployment. To learn more about setting your connection URI, see Connection URI.
The credentials for the authentication mechanism that you specified are correct. To learn how to specify your credentials, see the Authentication Mechanisms and Enterprise Authentication Mechanisms guides.
The name of the authentication database that you specified is correct. To learn how to set up the users and roles for your MongoDB deployment, see Manage Users and Roles in the Server documentation.
How do I prevent the "IllegalArgumentException: Invalid BSON field name" error?
Your application might throw this exception if you pass an incorrectly formatted document to an operation and you are using a driver version v4.7 or earlier.
Note
In driver versions v4.8 and later, this error message was replaced by one that includes more specific details on what was incorrectly formatted.
For example, the driver throws this error when you call an update operation and incorrectly omit the update operator as shown in the following code example:
// incorrectly formatted update document collection.updateOne( new Document().append("name", "fizz"), new Document().append("name", "buzz") );
To avoid this error, use the builder class for the appropriate operation. The driver offers builder classes to create syntactically correct BSON for MongoDB operations. The prior example can be correctly expressed using the builder classes as shown in the following code example:
// Builder class imports import static com.mongodb.client.model.Filters.*; import static com.mongodb.client.model.Updates.*; // ... collection.updateOne(eq("name", "fizz"), set("name", "buzz"));
To learn more about the available builders classes, see the Builders documentation.
How do I prevent the "IllegalStateException: state should be: open" error?
You may encounter this exception if you call an operation on a MongoClient
instance that closed its connections to MongoDB. Once the close()
method
is called on the MongoClient
, any further operation calls on that instance
throw this exception.
To avoid this exception, do not call operations on MongoClient
instance
after any code that calls close()
on it.
Tip
The code that closes the MongoClient
instance may be difficult to
locate in certain cases. To locate potential sources of this exception,
search for the following cases:
Calls to
close()
on aMongoClient
instanceOperation calls on a
MongoClient
instance that are outside the scope of the try-with-resources statement in which theMongoClient
is declared
If your application uses a framework to manage the MongoClient
such as Spring Boot, check the documentation of the framework to locate the
best practices for managing the connection behavior.
To learn more about accessing MongoDB from Spring Boot, see Spring Boot and MongoDB.
POJOs
Do I have to specify an ID field value myself?
No, the PojoCodecProvider
automatically generates an ObjectId.
Can the ID field be a compound key?
Yes. For an example of this, see our implementation
Can I use polymorphism in a POJO accessor?
Yes, by using a discriminator.
What is a discriminator?
A discriminator is a property that identifies a specific document schema. You can use it for inheritance and storing multiple types of documents within the same collection or parent document (if you embed subdocuments).
For example, if you have an Event
class that you extend in Java (e.g.
MachineEvent
or NetworkEvent
), using a discriminator identifies
which class the PojoCodecProvider
should use to serialize/deserialize the
document.
For more information, see our POJO Customization guide.
Can I control serialization of LocalDate
?
Yes, the 3.7 Java driver adds native support for JSR-310 Instant
,
LocalDate
& LocalDateTime
.
Can I serialize a java.util.Date
as a string in format yyyy-mm-dd?
Yes, you can build your own codec for this class and add it to the registry.
Add the codec to the first in the list of providers, before the default codec
registry and before the PojoCodecProvider
:
CodecRegistry registry = CodecRegistries.fromRegistries( CodecRegistries.fromCodecs( new MyDateAsStringCodec()), MongoClientSettings.getDefaultCodecRegistry(), fromProviders(pojoCodecProvider));
Can I make POJOs read/write directly to the field and not use the getters/setters at all?
You can configure the PojoCodecProvider
to use the
SET_PRIVATE_FIELDS_CONVENTION
, which sets a private field through
reflection if no public setter is available.
Can I mix private, protected, and public setters and getters?
No. The native POJO codec assumes that getters/setters have the same modifiers for each field.
For example, the following methods throws an exception during encoding:
private String getField(); public String setField(String x);
How do I fix: "org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class X."?
This exception means you need to register a codec for the class since there is none at the moment.
How do I specify the collection name for a particular POJO class? Is there an annotation?
There is no annotation. We recommend adding a static string in your class as shown:
public class Person { public static final String COLLECTION_NAME = "people"; }
The following snippet specifies the collection name for a particular POJO class:
database.getCollection(Person.COLLECTION_NAME, Person.class);
Legacy API
How do I connect to my MongoDB instance with the legacy API?
The following example shows how to connect to a MongoDB instance with the legacy API and the current API.
Imagine we are connecting to a collection that contains only this document:
{"_id": 1, "val": 1}
MongoClient client = new MongoClient(URI); DB db = client.getDB(DATABASE); DBCollection col = db.getCollection(COLLECTION); DBObject doc = col.find().one(); System.out.println(doc.toString());
MongoClient client = MongoClients.create(URI); MongoDatabase db = client.getDatabase(DATABASE); MongoCollection<Document> col = db.getCollection(COLLECTION); // Prints the first document retrieved from the collection as JSON Document doc = col.find().first(); System.out.println(doc.toJson());
The output of the preceding code snippet should look like this:
{"_id": 1, "val": 1}
For more information on the legacy classes and methods used in the preceding example, see the following API documentation pages:
See the Migrate from the Legacy API page for a list of differences between the legacy and current API.
How do I use the legacy MongoClientOptions
and MongoClientURI
Classes?
Here is an example showing how to use the legacy MongoClientOptions
and
MongoClientURI
classes to set your write concern:
MongoClientURI mongoURI = new MongoClientURI(URI, MongoClientOptions.builder() .writeConcern(WriteConcern.W1)); MongoClient client = new MongoClient(mongoURI);
MongoClientSettings options = MongoClientSettings.builder() .applyConnectionString(new ConnectionString(URI)) .writeConcern(WriteConcern.W1).build(); MongoClient client = MongoClients.create(options);
For more information on the legacy classes and methods used in the preceding example, see the following API Documentation pages:
See the Migrate from the Legacy API page for a list of differences between the legacy and current API.
Support
If you are unable to find the answer to your question here, try our forums and support channels listed in the Issues and Help section.