【问题标题】:MongoDB Java Inserting Throws org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class io.github.ilkgunel.mongodb.PojoMongoDB Java 插入引发 org.bson.codecs.configuration.CodecConfigurationException:找不到类 io.github.ilkgunel.mongodb.Pojo 的编解码器
【发布时间】:2017-01-18 21:57:40
【问题描述】:

我正在使用 Java 学习 MongoDB。我正在尝试使用 Java 驱动程序将数据插入 MongoDB。我正在像 MongoDB 教程中一样进行插入,而且一切都很好。但是如果我想插入一个变量,当我运行代码时,驱动程序会抛出这样的错误:

org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class io.github.ilkgunel.mongodb.Pojo.

我在 Stack Overflow 中搜索过这样的问题,但我什么都不懂,也找不到任何东西可以解决这个错误。我的代码如下。如何解决这个问题?

我正在使用此代码:

package io.github.ilkgunel.mongodb;
import org.bson.Document;

import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;

public class MongoDBBasicUsage {
    public static void main(String[] args) {
        MongoClient mongoClient;
        try {
            Pojo pojo = new Pojo();
            mongoClient = new MongoClient("localhost", 27017);
            MongoDatabase database = mongoClient.getDatabase("MongoDB");

            pojo.setId("1");
            pojo.setName("ilkay");
            pojo.setSurname("günel");

            Document document = new Document();
            document.put("person", pojo);

            database.getCollection("Records").insertOne(document);  
        } catch (Exception e) {
            System.err.println("Bir Hata Meydana Geldi!");
            System.out.println("Hata" + e);
        }
    }
}

我的 Pojo 是这样的:

    package io.github.ilkgunel.mongodb;

public class Pojo {
    String name;
    String surname;
    String id;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    } 
}

【问题讨论】:

    标签: java mongodb


    【解决方案1】:

    从您尝试执行的操作来看,您正在尝试添加一些自定义数据类型(在本例中为您的 POJO),但您需要记住的是文档中的字段只能接受某些数据类型,不是直接的对象。

    如果您也不知道,Mongo 文档的结构与 json 相同。因此,您必须通过创建字段并将值插入其中来显式创建文档。值字段中允许使用特定的数据类型:

    http://mongodb.github.io/mongo-java-driver/3.0/bson/documents/

    为了帮助您解决问题,下面的代码将您的 POJO 作为参数并知道 POJO 的结构,返回一个可以插入到您的集合中的 Mongo 文档:

    private Document pojoToDoc(Pojo pojo){
        Document doc = new Document();
    
        doc.put("Name",pojo.getName());
        doc.put("Surname",pojo.getSurname());
        doc.put("id",pojo.getId());
    
        return doc;
    } 
    

    这应该适用于插入。如果要索引其中一个字段:

    database.getCollection("Records").createIndex(new Document("id", 1));
    

    我希望这能回答您的问题并为您工作。

    【讨论】:

      【解决方案2】:

      您需要配置 CodeRegistry 以使用 PojoCodecProvider,如下所述: http://mongodb.github.io/mongo-java-driver/3.7/driver/getting-started/quick-start-pojo/

      【讨论】:

      • 当 OP 几年前提出这个问题时,不确定这个选项是否可用,但这是最好的解决方案,因为您使用的是 Mongo 的内置,而不是自己滚动。
      【解决方案3】:

      有点抽象,因为这可能会为其他开发人员节省一天的时间..
      此错误:CodecConfigurationException: Can't find a codec for class xxx 意味着您的 mongo 驱动程序无法处理您在由该 xxx 类创建的对象中发送的数据,因此无法生成您想要的 mongo 查询。

      在这种情况下,解决方案是使用正确的类,即使用驱动程序预期的类之一(在我的情况下,用 ArrayList 对象替换 java 数组解决了问题)。另一个解决方案可能是升级驱动程序。第三种解决方案可能是@Renato 提到的,用于定义您自己的解码逻辑。这取决于您的具体情况。
      hth

      【讨论】:

        【解决方案4】:

        在连接到 mongo db 以解决编解码器问题时使用下面的一组行,同时在 mongo 中使用 POJO 类。

        参考:https://developer.mongodb.com/quickstart/java-mapping-pojos

        ConnectionString connectionString = new ConnectionString("mongodb://" + username + ":" + password + "@" + host + ":" + port);
        CodecRegistry pojoCodecRegistry = fromProviders(PojoCodecProvider.builder().automatic(true).build());
        CodecRegistry codecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), pojoCodecRegistry);
        
        MongoClientSettings clientSettings = MongoClientSettings.builder()
                        .applyConnectionString(connectionString)
                        .codecRegistry(codecRegistry)
                        .build();
        MongoClient mongoClient = MongoClients.create(clientSettings);
        MongoDatabase mongoDatabase = mongoClient.getDatabase(database);
        

        【讨论】:

          【解决方案5】:

          文档: MongoDB Driver Quick Start - POJOs

          按照上面的文档,如果还是报错,那么

          您可以在您的集合中使用通用文档,例如

          class DocStore {
            String docId:
            String docType;
            Object document; // this will cause the BSON cast to throw a codec error
            Map<String, Object> document; // this won't
          }
          

          而且,您仍然希望投射您的文档 从 POJO地图

          mkyong 教程会有所帮助。

          至于提取,它按预期工作,但您可能希望从 Map 转换到您的 POJO 作为后处理步骤,我们可以找到一些很好的答案here

          希望对您有所帮助! ?️

          【讨论】:

            【解决方案6】:

            我正在使用MongoDB POJO support。就我而言,我在异常之前有这个“线索”警告:

             org.bson.codecs.pojo                     : Cannot use 'UserBeta' with the PojoCodec.
            
            org.bson.codecs.configuration.CodecConfigurationException: Property 'premium' in UserBeta, has differing data types: TypeData{type=PremiumStatus} and TypeData{type=Boolean}.
            

            我的班级UserBetagetPremium()setPremium()isPremium()。我已经@BsonIgnore-d isPremium() 但由于某种原因它仍然被检测到并导致冲突。

            我的解决方法是将isPremium() 重命名为isAnyPremium()

            【讨论】:

              【解决方案7】:

              我通过在 pom.xml 或 build.gradle 中添加 spring-boot-starter-data-mongodb 依赖项来解决它。

              compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-mongodb', version: '2.2.4.RELEASE'

              【讨论】:

                【解决方案8】:

                我的弹簧靴有这个问题。下面的代码解决了这个问题。

                创建梁。

                @Configuration
                @RequiredArgsConstructor
                public class MongoConfig {
                
                    private final MongodbProperties properties;
                
                    @Bean
                    public MongoClientSettings mongoClient() {
                        return MongoClientSettings.builder()
                                .applyToClusterSettings(builder -> builder.hosts(getServerAddress()))
                                .credential(getClientCredentials())
                                .codecRegistry(getCodecRegistry())
                                .build();
                    }
                
                    private CodecRegistry getCodecRegistry() {
                        return fromRegistries(MongoClientSettings.getDefaultCodecRegistry(),
                                fromProviders(PojoCodecProvider.builder().automatic(true).build()));
                    }
                
                    private List<ServerAddress> getServerAddress() {
                        return Collections.singletonList(new ServerAddress(properties.getHost(), properties.getPort()));
                    }
                
                    private MongoCredential getClientCredentials() {
                        return MongoCredential
                                .createCredential(properties.getUsername(), properties.getAuthenticationDatabase(),
                                        properties.getPassword().toCharArray());
                    }
                }
                

                从 application.yml 文件中获取属性。

                @Getter
                @Setter
                @Configuration
                public class MongodbProperties {
                
                    @Value("${spring.data.mongodb.host}")
                    private String host;
                
                    @Value("${spring.data.mongodb.database}")
                    private String database;
                
                    @Value("${spring.data.mongodb.authentication-database}")
                    private String authenticationDatabase;
                
                    @Value("${spring.data.mongodb.port}")
                    private int port;
                
                    @Value("${spring.data.mongodb.username}")
                    private String username;
                
                    @Value("${spring.data.mongodb.password}")
                    private String password;
                }
                

                【讨论】:

                  【解决方案9】:

                  你检查过 mongodb 的库吗?我今天早上通过将 mongodb java 驱动程序从 3.2.2 更改为 3.4.2 解决了这个问题。 像这样的新专家:

                  <dependency>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-starter-data-mongodb</artifactId>
                      <version>1.5.4.RELEASE</version>
                  </dependency>
                  

                  试一试并回复

                  【讨论】:

                  • 在 mongodb-driver 3.6.4 上仍然失败,所以 - 否
                  • 这与 PO 的要求无关。您的答案引用驱动器,但代码显示弹簧框架,与原始问题无关。
                  猜你喜欢
                  • 2019-06-19
                  • 2017-04-07
                  • 2018-11-01
                  • 2019-08-31
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多