Docs Menu
Docs Home
/ / /
Java Sync Driver

FAQ

On this page

  • General
  • What if I can't connect to a MongoDB instance?
  • 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 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 and MongoClientURI Classes?
  • Support

If you have trouble connecting to a MongoDB deployment, see the Connection Troubleshooting Guide for possible solutions.

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.

New applications generally use the com.mongodb.client.MongoClient interface, which supports:

  • Configuration with MongoClientSettings and ConnectionString. You can create instances of this interface via factory methods defined in the com.mongodb.client.MongoClients class.

  • CRUD API using MongoDatabase, and from there, MongoCollection

Use the com.mongodb.MongoClient class if you require support for the legacy API, which supports:

  • Configuration with MongoClientOptions and MongoClientURI

  • CRUD API using DB, and from there, DBCollection. You can access this API via the getDB() method.

For applications that require a mix of the new and legacy APIs, com.mongodb.MongoClient also supports:

  • Configuration with MongoClientSettings and ConnectionString, 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 the getDatabase() method.

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 about the MongoClientSettings class, see the API Documentation for MongoClientSettings.

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 multi-threaded 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.

You might 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 might be missing from your classpath. To locate the driver JAR that the error refers to, check each of the entries in the API documentation.

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.

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.

You might 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 might be difficult to locate in certain cases. To locate potential sources of this exception, search for the following cases:

  • Calls to close() on a MongoClient instance

  • Operation calls on a MongoClient instance that are outside the scope of the try-with-resources statement in which the MongoClient 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.

No, the PojoCodecProvider automatically generates an ObjectId.

Yes. For an example of this, see our implementation

Yes, by using 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, such as MachineEvent or NetworkEvent, using a discriminator identifies which class the PojoCodecProvider must use to serialize and deserialize the document.

For more information, see the POJO Customization guide.

Yes, the 3.7 Java driver adds native support for JSR-310 Instant, LocalDate & LocalDateTime.

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));

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.

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);

This exception means you must register a codec for the class since there is none at the moment.

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);

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);
// Retrieves one document in the collection and prints it
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 resembles the following:

{"_id": 1, "val": 1}

For more information about 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.

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 about 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.

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.

Back

API Documentation