Perguntas frequentes
Nesta página
- Em geral
- Por que existem dois tipos de
MongoClient
no driver Java? - Que tipo de
MongoClient
devo usar? - Como eu uso a classe
MongoClientSettings
? - Como corrigir: "javax.net.ssl.SSLHandshakeException: a extensão (5) não deve ser apresentada em certificado_request"?
- Como funciona o pool de conexões no driver Java?
- Como evito o erro "java.lang.NoClassDefFoundError: com/mongodb/MongoClient"?
- Como evito o erro "com.mongodb.MongoSecurityException"?
- Como evito o erro "IllegalArgumentException: Nome de campo BSON inválido"?
- Como evito o erro "IllegalStateException: o estado deve ser: aberto"?
- POJOs
- Preciso especificar um valor de campo de ID sozinho?
- O campo ID pode ser uma chave composta?
- Posso usar polimorfismo em um acessador POJO?
- O que é um discriminador?
- Posso controlar a serialização do
LocalDate
? - Posso serializar um
java.util.Date
como uma string no formato ayyyy-mm-DD? - Posso fazer com que os POJOs leiam/gravem diretamente no campo e não usem os getters/setters?
- Posso misturar setters e getters privados, protegidos e públicos?
- Como corrigir: "org.bson.codecs.configuration.CodecConfigurationException: Não é possível encontrar um codec para a classe X."?
- Como faço para especificar o nome da collection para uma classe POJO específica? Há uma anotação?
- Legacy API
- Como me conectei à minha instância do MongoDB com a API legada?
- Como eu uso as classes legadas
MongoClientOptions
eMongoClientURI
? - Suporte
Em geral
Por que existem dois tipos de MongoClient
no driver Java ?
Há dois tipos de MongoClient
porque queríamos uma API mais limpa que não incluísse várias APIs CRUD para não confundir usuários novatos. Queríamos garantir que a nova API CRUD estivesse disponível em uma estrutura de pacote Java que funcionasse bem com o suporte ao módulo Java introduzido no Java 9.
Que tipo de MongoClient
devo usar?
Novos aplicativos geralmente devem usar a interface com.mongodb.client.MongoClient
, que suporta:
Configuração com
MongoClientSettings
eConnectionString
. Você pode criar instâncias desta interface por meio de métodos de fábrica definidos na classecom.mongodb.client.MongoClients
.API CRUD usando
MongoDatabase
e, a partir desse ponto,MongoCollection
Você deve usar a classe com.mongodb.MongoClient
se precisar de suporte para a API legada, que suporta:
Configuração com
MongoClientOptions
eMongoClientURI
API CRUD usando
DB
e, a partir daqui,DBCollection
. Você pode acessar esta API por meio do métodogetDB()
.
Para aplicação que exigem uma combinação de API novas e legado, o com.mongodb.MongoClient
também suporta:
Configuração com
MongoClientSettings
eConnectionString
, a única diferença é que você cria instâncias por meio de construtores em vez de uma classe de fábrica.API CRUD usando
MongoDatabase
e, a partir daqui,MongoCollection
. Você pode acessar esta API por meio do métodogetDatabase()
.
Como uso a MongoClientSettings
classe ?
Você pode utilizar a classe MongoClientSettings
para especificar configurações para instâncias do MongoClient
. Para construir instâncias do MongoClientSettings
, utilize a classe MongoClientSettings.Builder
.
Aqui estão as seções de nossa documentação que mostram como executar diferentes tarefas com a classe MongoClientSettings
:
Para obter mais informações sobre a MongoClientSettings
classe , consulte a documentação da API para MongoClientSettings.
Como corrigir: "javax.net.ssl.SSLHandshakeException: a extensão (5) não deve ser apresentada em certificado_request"?
Este é um erro conhecido que pode ocorrer ao usar o TLS 1.3 protocolo com versões específicas do JDK. Se você encontrar esse erro ao se conectar à sua instância ou cluster do MongoDB, atualize seu JDK para uma das seguintes versões de patch ou mais recente:
JDK 11.0.7
JDK 13.0.3
JDK 14.0.2
Como funciona o pool de conexões no driver Java?
Cada instância MongoClient
tem um pool de conexões integrado para cada servidor em sua topologia do MongoDB. O pool de conexões abre soquetes sob demanda para oferecer suporte às operações simultâneas do MongoDB em sua aplicação de threads múltiplas.
O tamanho máximo de cada conjunto de conexões é definido pela opção maxPoolSize
, que padroniza para 100
. Se o número de conexões em uso com um servidor atingir o valor de maxPoolSize
, a próxima solicitação para esse servidor aguardará até que uma conexão fique disponível.
Cada instância MongoClient
abre dois soquetes adicionais por servidor em sua topologia MongoDB para monitorar o estado do servidor.
Por exemplo, um cliente conectado a um conjunto de réplicas de 3 nós abre 6 soquetes de monitoramento. Ele também abre quantos soquetes forem necessários para oferecer suporte aos threads de um aplicativo em cada servidor, até o valor de maxPoolSize
. Se maxPoolSize
for 100
e o aplicativo usar apenas o primário (o padrão), somente o pool de conexões primárias crescerá e poderá haver no máximo 106
conexões totais. Se a aplicação usar uma preferência de leitura para consultar os nós secundários, seus pools também crescerão e poderá haver um total 306
conexões.
Além disso, os pools de conexões têm taxa limitada de modo que cada pool de conexões só pode criar, no máximo, o valor de maxConnecting
conexões em paralelo a qualquer momento. Qualquer thread adicional para de esperar nos seguintes casos:
Um dos threads existentes termina de criar uma conexão, ou uma conexão existente é verificada novamente no pool.
A capacidade do driver de reutilizar conexões existentes melhora devido aos limites de taxa na criação de conexões.
Você pode configurar o número mínimo de conexões simultâneas para cada servidor com a opção minPoolSize
, que padroniza para 0
. O pool de conexões será inicializado com este número de tomadas. Se os soquetes forem fechados devido a qualquer erro de rede, fazendo com que o número total de soquetes (em uso e ociosos) caia abaixo do mínimo, mais soquetes serão abertos até que o mínimo seja atingido.
Você pode definir o número máximo de milésimos de segundo que uma conexão pode permanecer ociosa no grupo antes de ser removida e substituída pela opção maxIdleTimeMS
, que padroniza para 0
(sem limite).
A seguinte configuração padrão para um MongoClient
funciona para a maioria dos aplicativos:
MongoClient client = new MongoClient("<connection string>")
Crie um cliente uma vez para cada processo e reutilize-o para todas as operações. É um erro comum criar um novo cliente para cada solicitação, o que é muito ineficiente.
Para oferecer suporte a um grande número de operações simultâneas do MongoDB em um processo, você pode aumentar o maxPoolSize
. Quando o pool atinge seu tamanho máximo, threads adicionais aguardam a disponibilidade de soquetes.
O driver não limita o número de threads que podem aguardar a disponibilidade de soquetes, e é responsabilidade do aplicativo limitar o tamanho de seu pool para limitar o enfileiramento durante um pico de carga. Os threads aguardam a quantidade de tempo especificada na opção waitQueueTimeoutMS
, que padroniza para 120000
, ou 120 segundos.
Um thread que aguarda mais do que o período de tempo definido por waitQueueTimeoutMS
para um soquete gera um erro de conexão. Use essa opção se for mais importante limitar a duração das operações durante um pico de carga do que concluir cada operação.
Quando MongoClient.close()
é chamado por qualquer thread, o driver fecha todos os soquetes ociosos e fecha todos os soquetes que estão em uso à medida que são retornados ao pool.
Como evito o erro "java.lang.NoClassDefFoundError: com/mongodb/MongoClient"?
Você pode encontrar uma exceção java.lang.NoClassDefFoundError
quando seu ambiente de execução Java não conseguir localizar um arquivo de classe no tempo de execução. Ao tentar executar o código do aplicativo que usa o MongoDB Java Driver, você deve incluir os arquivos JAR do driver apropriados no classpath.
Se você receber esse erro depois de adicionar os arquivos JAR do driver Java ao seu classpath, verifique os seguintes itens no seu ambiente:
Os arquivos JAR existem nos locais especificados pelo classpath.
A sintaxe do classpath está correta.
Se você definir o classpath em uma variável de ambiente, o ambiente de tempo de execução Java utilizará esta variável.
Se você usar um gerenciador de dependências, ele não relatará nenhum conflito não resolvido.
Dica
Esse erro contém o pacote e o nome da classe, o que pode ajudá-lo a identificar qual driver JAR pode estar faltando no seu classpath. Para localizar o JAR do driver a que o erro se refere, verifique cada uma das entradas na documentação da API.
Como evito o erro "com.mongodb.MongoSecurityException"?
Seu aplicativo poderá lançar essa exceção se você especificar credenciais inválidas ou formatadas incorretamente ao se conectar a um sistema do MongoDB.
Se você receber esse erro ao tentar se conectar a um sistema do MongoDB, verifique os seguintes itens no seu código:
O URI de conexão corresponde à implantação correta do MongoDB. Para saber mais sobre como definir seu URI de conexão, consulte URI de conexão.
As credenciais do mecanismo de autenticação que você especificou estão corretas. Para saber como especificar suas credenciais, consulte os guias mecanismo de autenticação e autenticação empresarial .
O nome do banco de dados de autenticação que você especificou está correto. Para saber como configurar os usuários e as funções de seu MongoDB deployment, consulte Gerenciar usuários e funções na documentação do Servidor MongoDB.
Como evito o erro "IllegalArgumentException: Nome de campo BSON inválido"?
Seu aplicativo poderá lançar essa exceção se você passar um documento formatado incorretamente para uma operação e estiver usando um driver versão v4.7 ou anterior.
Observação
Nas versões v4.8 e posterior do driver, essa mensagem de erro foi substituída por uma que inclui detalhes mais específicos sobre o que foi formatado incorretamente.
Por exemplo, o driver lança esse erro quando você chama uma operação de atualização e omite incorretamente o operador de atualização, conforme mostrado no exemplo de código a seguir:
// incorrectly formatted update document collection.updateOne( new Document().append("name", "fizz"), new Document().append("name", "buzz") );
Para evitar esse erro, use a classe do construtor para a operação apropriada. O driver oferece classes de construtores para criar operações BSON sintaxe corretas para MongoDB. O exemplo anterior pode ser expresso corretamente utilizando as classes de construtor como mostrado no seguinte exemplo de código:
// 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"));
Para saber mais sobre as classes de construtores disponíveis, consulte a documentação de Construtores .
Como evito o erro "IllegalStateException: o estado deve ser: aberto"?
Você pode encontrar essa exceção se chamar uma operação em uma instância do MongoClient
que fechou suas conexões com o MongoDB. Depois que o método close()
for chamado em MongoClient
, qualquer operação adicional chamada nessa instância gerará essa exceção.
Para evitar essa exceção, não chame operações na instância MongoClient
após qualquer código que chame close()
nela.
Dica
O código que fecha a instância do MongoClient
pode ser difícil de localizar em determinados casos. Para localizar possíveis fontes dessa exceção, pesquisar os seguintes casos:
Chamadas para
close()
em uma instância doMongoClient
A operação chama uma instância
MongoClient
que está fora do escopo da declaração de tentativa com recursos na qual oMongoClient
é declarado
Se sua aplicação usar uma estrutura para managed o MongoClient
, como oSpring Boot, verifique a documentação da estrutura para localizar as melhores práticas para managed o comportamento da conexão.
Para saber mais sobre como acessar o MongoDB a partir do Spring Boot, consulte Spring Boot e MongoDB.
POJOs
Preciso especificar um valor de campo de ID sozinho?
Não, o PojoCodecProvider
gera automaticamente um ObjectId.
O campo ID pode ser uma chave composta?
Sim. Para ver um exemplo disso, consulte nossa implementação
Posso usar polimorfismo em um acessador POJO?
Sim, usando um discriminador.
O que é um discriminador?
A discriminator is a property that identifies a specific document schema. Você pode usá-lo para herança e armazenar vários tipos de documento dentro da mesma collection ou documento pai (se você incorporar subdocumentos).
Por exemplo, se você tiver uma classe Event
que você estenda em Java (por exemplo MachineEvent
ou NetworkEvent
), o uso de um discriminador identifica qual classe o PojoCodecProvider
deve usar para serializar/desserializar o documento.
Para obter mais informações, consulte nosso guia de personalização POJO.
Posso controlar a serialização do LocalDate
?
Sim, o driver Java 3.7 adiciona suporte nativo para JSR-310 Instant
, LocalDate
e LocalDateTime
.
Posso serializar um java.util.Date
como uma string no formato ayyyy-mm-dd?
Sim, você pode construir seu próprio codec para esta classe e adicioná-lo ao registro.
Adicione o codec ao primeiro na lista de fornecedores, antes do registro de codecs padrão e antes do PojoCodecProvider
:
CodecRegistry registry = CodecRegistries.fromRegistries( CodecRegistries.fromCodecs( new MyDateAsStringCodec()), MongoClientSettings.getDefaultCodecRegistry(), fromProviders(pojoCodecProvider));
Posso fazer com que os POJOs leiam/gravem diretamente no campo e não usem os getters/setters?
Você pode configurar o PojoCodecProvider
para usar o SET_PRIVATE_FIELDS_CONVENTION
, que define um campo privado por meio de reflexão se nenhum configurador público estiver disponível.
Posso misturar setters e getters privados, protegidos e públicos?
Não. O codec POJO nativo pressupõe que getters/setters têm os mesmos modificadores para cada campo.
Por exemplo, os métodos a seguir lançam uma exceção durante a codificação:
private String getField(); public String setField(String x);
Como corrigir: "org.bson.codecs.configuration.CodecConfigurationException: Não é possível encontrar um codec para a classe X."?
Essa exceção significa que você precisa registrar um codec para a classe, pois não há nenhum no momento.
Como faço para especificar o nome da collection para uma classe POJO específica? Há uma anotação?
Não há anotação. Recomendamos adicionar uma string estática em sua classe, conforme mostrado:
public class Person { public static final String COLLECTION_NAME = "people"; }
O seguinte trecho especifica o nome da collection para uma classe POJO:
database.getCollection(Person.COLLECTION_NAME, Person.class);
Legacy API
Como me conectei à minha instância do MongoDB com a API legada?
O exemplo a seguir mostra como se conectar a uma instância MongoDB com a API legada e a API atual.
Imagine que estamos nos conectando a uma collection que contém apenas este documento:
{"_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());
A saída do trecho de código anterior deve ser semelhante a esta:
{"_id": 1, "val": 1}
Para obter mais informações sobre as classes e métodos legados usados no exemplo anterior, consulte as seguintes páginas de documentação da API:
Consulte a página Migrar da API legado para obter uma lista das diferenças entre a API legado e a atual.
Como uso as classes MongoClientOptions
e MongoClientURI
legado ?
Aqui está um exemplo mostrando como usar as classes de legado MongoClientOptions
e MongoClientURI
para definir sua referência de escrita:
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);
Para obter mais informações sobre as classes e métodos legados usados no exemplo anterior, consulte as seguintes páginas de documentação da API:
Consulte a página Migrar da API legado para obter uma lista das diferenças entre a API legado e a atual.
Suporte
Se você não conseguir encontrar a resposta para sua pergunta aqui, experimente nossos fóruns e canais de suporte listados na seção Problemas e Ajuda.