Watch keynotes and sessions from MongoDB.live, our virtual developer conference.

MongoDB CodecConfigurationException for Kotlin data class

I am getting Cannot find a public constructor for 'TodoItem' when trying to query the MondoDB collection. I am assuming the kotlin data classes have public constructor by default.

Can someone help me out? I am new to kotlin and mongo db.

Cannot find a public constructor for 'TodoItem'.

A custom Codec or PojoCodec may need to be explicitly configured and registered to handle this type.
        at org.bson.codecs.pojo.AutomaticPojoCodec.decode(AutomaticPojoCodec.java:40) ~[bson-4.0.3.jar:na]
        at com.mongodb.internal.operation.CommandResultArrayCodec.decode(CommandResultArrayCodec.java:52) ~[mongodb-driver-core-4.0.3.jar:na]
        at com.mongodb.internal.operation.CommandResultDocumentCodec.readValue(CommandResultDocumentCodec.java:60) ~[mongodb-driver-core-4.0.3.jar:na]
        at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:84) ~[bson-4.0.3.jar:na]
        at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:41) ~[bson-4.0.3.jar:na]
        at org.bson.internal.LazyCodec.decode(LazyCodec.java:48) ~[bson-4.0.3.jar:na]
        at org.bson.codecs.BsonDocumentCodec.readValue(BsonDocumentCodec.java:101) ~[bson-4.0.3.jar:na]
        at com.mongodb.internal.operation.CommandResultDocumentCodec.readValue(CommandResultDocumentCodec.java:63) ~[mongodb-driver-core-4.0.3.jar:na]
        at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:84) ~[bson-4.0.3.jar:na]
        at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:41) ~[bson-4.0.3.jar:na]
...
Caused by: org.bson.codecs.configuration.CodecConfigurationException: Cannot find a public constructor for 'TodoItem'.
        at org.bson.codecs.pojo.CreatorExecutable.checkHasAnExecutable(CreatorExecutable.java:140) ~[bson-4.0.3.jar:na]
        at org.bson.codecs.pojo.CreatorExecutable.getInstance(CreatorExecutable.java:107) ~[bson-4.0.3.jar:na]
        at org.bson.codecs.pojo.InstanceCreatorImpl.<init>(InstanceCreatorImpl.java:40) ~[bson-4.0.3.jar:na]
        at org.bson.codecs.pojo.InstanceCreatorFactoryImpl.create(InstanceCreatorFactoryImpl.java:28) ~[bson-4.0.3.jar:na]
        at org.bson.codecs.pojo.ClassModel.getInstanceCreator(ClassModel.java:75) ~[bson-4.0.3.jar:na]
        at org.bson.codecs.pojo.PojoCodecImpl.decode(PojoCodecImpl.java:121) ~[bson-4.0.3.jar:na]
        at org.bson.codecs.pojo.PojoCodecImpl.decode(PojoCodecImpl.java:126) ~[bson-4.0.3.jar:na]
        at org.bson.codecs.pojo.AutomaticPojoCodec.decode(AutomaticPojoCodec.java:37) ~[bson-4.0.3.jar:na]
        ... 98 common frames omitted

  • Data class TodoItem
@GraphQLDescription("Type for TodoItem")
data class TodoItem(
    val id: Long,
    val details: String,
    val status: String
)

  • DTO Code
@Component
class TodoItemDto() {

    private val mongoClient: MongoClient

    init {
        val codecRegistry: CodecRegistry = fromRegistries(
            MongoClientSettings.getDefaultCodecRegistry(),
            fromProviders(
                PojoCodecProvider.builder()
                    .automatic(true)
                    .build()
            )
        )
        val settings: MongoClientSettings = MongoClientSettings.builder()
            .codecRegistry(codecRegistry)
            .build()
        mongoClient = MongoClients.create(settings)
    }

    fun getTodoItemList(): List<TodoItem> {
        return getCollection().find()
            .toList()
    }

    private fun getCollection(): MongoCollection<TodoItem> {
        val database: MongoDatabase = mongoClient.getDatabase("TodoItemsDB")

        return database.getCollection("todoItem", TodoItem::class.java)
    }
}

Code repository: https://github.com/sashwatp/kotlin-graphql-server

The Pojo (plain old Java Object) class TodoItem.java needs a constructor. Also, if you are reading and setting values to the object you need to provide get / set methods within the class. See this: POJOS (MongoDB Java Deriver).

Yes, the class has a default no-argument constructor (as you have not defined any). The driver is expecting a constructor with arguments - the arguments with which to construct an object using the state (the instance variables) you have defined in the class.

2 Likes