简体   繁体   English

MongoDB Java 插入引发 org.bson.codecs.configuration.CodecConfigurationException:找不到类 io.github.ilkgunel.mongodb.Pojo 的编解码器

[英]MongoDB Java Inserting Throws org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class io.github.ilkgunel.mongodb.Pojo

I'm learning MongoDB with Java.我正在用 Java 学习 MongoDB。 I'm trying to insert data to MongoDB with Java driver.我正在尝试使用 Java 驱动程序将数据插入 MongoDB。 I'm doing inserting like in MongoDB tutorial and every thing is okey.我正在像 MongoDB 教程中一样进行插入,而且一切都很好。 But if I want to insert a variable and when I run the code, driver throws an error like this:但是如果我想插入一个变量并且当我运行代码时,驱动程序会抛出这样的错误:

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

I searhed questions in Stack Overflow like this but I couldn't understand anything and I cant't find anything to solve this error.我像这样在 Stack Overflow 中搜索了问题,但我什么都不懂,也找不到任何东西来解决这个错误。 My code is below.我的代码如下。 How can solve this problem?如何解决这个问题?

I'm using this code:我正在使用这段代码:

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

My Pojo is this:我的 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;
    } 
}

From the looks of what you are trying to do, you are trying to add some custom data type (in this case your POJO) but what you need to keep in mind is that fields in documents can only accept certain data types, not objects directly.从您尝试做的事情来看,您正在尝试添加一些自定义数据类型(在这种情况下是您的 POJO),但您需要记住的是文档中的字段只能接受某些数据类型,而不是直接接受对象.

In case if you didn't know also, Mongo Documents are structured the same way as json.如果您也不知道,Mongo 文档的结构与 json 相同。 So you have to explicitaly create the documents by creating the fields and inserting the values into them.因此,您必须通过创建字段并将值插入其中来显式创建文档。 There are specific data types that are allowed in value fields:值字段中允许使用特定的数据类型:

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

To help with your case, the code below takes your POJO as a parameter and knowing the structure of the POJO, returns a Mongo Document that can be inserted into your collection:为了帮助您解决问题,下面的代码将您的 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;
} 

This should work for insertion.这应该适用于插入。 If you want to index one of the fields:如果要索引其中一个字段:

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

I hope this answers your question and works for you.我希望这能回答你的问题并为你工作。

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

To be bit abstract, as this may save the day for other developers..有点抽象,因为这可能会为其他开发人员节省一天的时间。
This error: CodecConfigurationException: Can't find a codec for class xxx means that your mongo driver is not able to handle the data you sent in the object you made of that xxx class and accordingly can't generate the mongo query you want.此错误: CodecConfigurationException: Can't find a codec for class xxx意味着您的 mongo 驱动程序无法处理您在由该 xxx 类创建的对象中发送的数据,因此无法生成您想要的 mongo 查询。

The resolution in that case would be either to use the right class ie to use one of the expected classes by the driver (in my case replacing java array by ArrayList object resolved the issue).. The other resolution could be to upgrade your driver.在这种情况下,解决方案是使用正确的类,即使用驱动程序预期的类之一(在我的情况下,用 ArrayList 对象替换 java 数组解决了问题)。另一个解决方案可能是升级驱动程序。 Third solution could be as mentioned by @Renato, to define your own decoding logic.. This depends on your exact case.第三种解决方案可能是@Renato 提到的,用于定义您自己的解码逻辑。这取决于您的具体情况。
hth hth

Use below set of lines while making connection to mongo db for resolving the issue with codec, while using POJO class in mongo.在连接到 mongo db 以解决编解码器问题时使用下面的一组行,同时在 mongo 中使用 POJO 类。

Reference : https://developer.mongodb.com/quickstart/java-mapping-pojos参考: 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);

Documentation: MongoDB Driver Quick Start - POJOs文档: MongoDB 驱动程序快速入门 - POJO

After following the above document, if you are still getting error, then按照上述文档操作后,如果仍然出现错误,那么

you could be using a generic document inside your collection like你可以在你的集合中使用一个通用文档,比如

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
}

And still, you would want to cast your document from POJO to Map而且,您仍然希望将您的文档从POJO转换为Map

mkyong tutorial could help. mkyong教程可以提供帮助。

As for the fetch, it works as expected but you might want to cast from Map to your POJO as a post-processing step, we can find some good answers here至于获取,它按预期工作,但您可能希望从 Map 转换到您的 POJO 作为后处理步骤,我们可以在这里找到一些好的答案

Hope it helps!希望能帮助到你! 🙂️ 🙂️

I'm using MongoDB POJO support .我正在使用MongoDB POJO 支持 In my case, I had this "clue" WARNing before the exception:就我而言,我在异常之前有这个“线索”警告:

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

My class UserBeta had getPremium() , setPremium() , and isPremium() .我的UserBeta类有getPremium()setPremium()isPremium() I already @BsonIgnore -d the isPremium() but for some reason it's still detected and causing conflict.我已经@BsonIgnore -d isPremium()但由于某种原因它仍然被检测到并导致冲突。

My workaround is to rename isPremium() to isAnyPremium() .我的解决方法是将isPremium()重命名为isAnyPremium()

我通过在 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'

I had this problem with the spring boot.我的弹簧靴有这个问题。 The code below solved the problem.下面的代码解决了这个问题。

Creating beam.创建梁。

@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());
    }
}

Getting properties from application.yml file.从 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;
}

MongoDB driver couldn't understand your POJO, So it is asking for a way to convert it to the BSON document. MongoDB 驱动程序无法理解您的 POJO,因此它正在寻求一种将其转换为 BSON 文档的方法。 So, Instead of defining codecs for each object, it is better to convert POJO into the document and use it further.因此,与其为每个对象定义编解码器,不如将 POJO 转换为文档并进一步使用。

Just convert it using object mapper/ GSON and parse it using org.bson.Document class.只需使用对象映射器/ GSON 转换它并使用org.bson.Document类对其进行解析。

ObjectMapper objectMapper = new ObjectMapper(); //Advisable to create and consume as bean
Document pojoDocument = Document.parse(objectMapper.writeValueAsString(pojo));

Then you can fed the pojoDocument into the mongo client methods.然后您可以将 pojoDocument 输入到 mongo 客户端方法中。

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

database.getCollection("Records").insertOne(document); 

did you check the library of mongodb.你检查过 mongodb 的库吗? I solve this problem in this morning by change the mongodb java driver from 3.2.2 to 3.4.2.我今天早上通过将 mongodb java 驱动程序从 3.2.2 更改为 3.4.2 解决了这个问题。 the new maven like that:像这样的新行家:

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

have a try and response试一试

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 org.bson.codecs.configuration.CodecConfigurationException:找不到类 org.hibernate.ogm.datastore.mongodb.type.GridFS 的编解码器 - org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class org.hibernate.ogm.datastore.mongodb.type.GridFS MongoDB jodatime:org.bson.codecs.configuration.CodecConfigurationException:找不到类org.joda.time.DateTime的编解码器 - MongoDB jodatime: org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class org.joda.time.DateTime MongoDB Java插入引发找不到类org.variabel.BsonDocument的编解码器 - MongoDB Java Inserting Throws Can't find a codec for class org.variabel.BsonDocument MongoDB 的不可变自动生成存储库抛出“找不到接口的编解码器” CodecConfigurationException - Immutables Autogenerated repository for MongoDB throws "Can't find a codec for interface" CodecConfigurationException 找不到我的课程的编解码器(CodecConfigurationException) - Can't find a codec for my class (CodecConfigurationException) Morphia - CodecConfigurationException:找不到类的编解码器 - 但类已注册 - Morphia - CodecConfigurationException: Can't find a codec for class - But class is registered spring-boot 2.1.0 mongo-CodecConfigurationException:找不到类java.time.Year的编解码器 - spring-boot 2.1.0 mongo - CodecConfigurationException: Can't find a codec for class java.time.Year (聚合)找不到类org.springframework.data.mongodb.core.geo.GeoJsonPoint的编解码器 - (Aggregation) Can't find a codec for class org.springframework.data.mongodb.core.geo.GeoJsonPoint 找不到类org.springframework.data.mongodb.core.query.GeoCommand的编解码器 - Can't find a codec for class org.springframework.data.mongodb.core.query.GeoCommand MongoDB Java CodecConfigurationException 找不到公共构造函数 - MongoDB Java CodecConfigurationException Cannot find a public constructor for
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM