Can't find a codec for my class

22,800

Solution 1

You need to configure a CodecRegistry which will manage the translation from bson to your pojos:

MongoClientURI connectionString = new MongoClientURI("mongodb://localhost:27017");
MongoClient mongoClient = new MongoClient(connectionString);
CodecRegistry pojoCodecRegistry = org.bson.codecs.configuration.CodecRegistries.fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), org.bson.codecs.configuration.CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build()));
MongoDatabase database = mongoClient.getDatabase("testdb").withCodecRegistry(pojoCodecRegistry);  

PS: You could statically import org.bson.codecs.configuration.CodecRegistries.fromRegistries and org.bson.codecs.configuration.CodecRegistries.fromProviders.

A full example could be found in github.
The Mongodb java driver documentation contains also an article about managing pojos (The link is for the 3.8.0 driver version).

Solution 2

Follow the quick start guide for POJO. You need to register the codec to make the translation of your POJOs (Plain Old Java Object) to/from BSON: http://mongodb.github.io/mongo-java-driver/3.7/driver/getting-started/quick-start-pojo/

Solution 3

Documentation: MongoDB Driver Quick Start - POJOs

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

mkyong comes to rescue.

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

Hope it helps! 🙂️

Solution 4

Have you annotated your Java class? Looks like you need a @Entity above your class and @Id above your ID field.

Share:
22,800
Darshan Puranik
Author by

Darshan Puranik

I am a Research Assistant at IUPUI. I am interested in Distributed Systems, Software Instrumentation and Web Technologies.

Updated on July 22, 2022

Comments

  • Darshan Puranik
    Darshan Puranik almost 2 years

    I have simple class named Signal. Class looks as follows:

    public class Signal {
        private String id;
        private Date timestamp;
    
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
        public Date getTimestamp() {
            return timestamp;
        }
        public void setTimestamp(Date timestamp) {
            this.timestamp = timestamp;
        }
    }
    

    I am trying to insert signal in MongoDB (v3.4). I am using the following method to insert:

    public boolean xyz(Signal signal) {
                try {
                    DatabaseConnection databaseConnection =DatabaseConnection.getInstance();
                    MongoClient mongoClient = databaseConnection.getMongoClient();
                    MongoDatabase db = mongoClient.getDatabase("myDb"); 
                    MongoCollection<Signal> collection = db.getCollection("myCollection", Signal.class);
                    collection.insertOne(signal);
    
                    return true;
                } catch (Exception e){
                    logger.error("Error", e);
                    return false;
                }
    
            }
    

    I am getting the following exception:

    org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class in.co.mysite.webapi.models.Signal.

    I checked a similar question here but insertion code is different. I took the hint from answer and modified my method but it doesn't look clean. Modified method is as follows:

    public boolean xyz(Signal signal) {
            try {
                DatabaseConnection databaseConnection =DatabaseConnection.getInstance();
                MongoClient mongoClient = databaseConnection.getMongoClient();
                MongoDatabase db = mongoClient.getDatabase("myDb"); 
                MongoCollection<Document> collection = db.getCollection("myCollection");
    
                Document doc = new Document();
    
                doc.put("id", signal.getId());
                doc.put("timestamp", signal.getTimestamp());
                doc.put("_id", new ObjectId().toString());
    
                collection.insertOne(doc);
    
                return true;
            } catch (Exception e){
                logger.error("Error", e);
                return false;
            }
    
        }
    
  • Darshan Puranik
    Darshan Puranik over 6 years
    I purposely didnt annotate because "signal" is technically not an entity according to my architecture/logic.
  • Nic Cottrell
    Nic Cottrell over 6 years
    But your saving it with Morphia as an entity and it is the top level representation of a collection, so it is an entity in this context