Repository layer for MongoDB
Your properties are nullable even tough they are never null and assigned in the constructor. Declare them as

protected val database: MongoDatabase


This way, the child classes can access them without needing the safe-call operator and also you prevent them from overwriting the property.

Also, both of your methods call database.getCollection("users"). This is a sign that you need to extract the collection to a property rather than the database or client.

Also, it's better to pass a MongoClient or even a MongoDatabase to the constructor because it can be shared between multiple repositories and follows the dependency injection pattern.

Because you now have only one property, you can drop the init block.

abstract class BaseRepository&lt;Entity&gt;(db: MongoDatabase, collectionName: String) {
    protected val collection = db.getCollection(collectionName)

    abstract fun insertOne(e: Entity)

    abstract fun findOne(username: String) : Entity
}


I also got rid of the unnecessary semicolons.

Now to the child class. val userDocument =  collection?.find(Document("username", username))?.first() returns a nullable  Document?. But in the line below you cast the members to String which will throw an exception if the value was null. To get proper null safety, declare the return type of the method as nullable

abstract fun findOne(username: String) : Entity?


and rewrite the implementation, e.g. like so

override fun findOne(username: String): User? {
    val userDocument = collection.find(Document("username", username)).first() ?: return null

    return User(
            userDocument.get("chatId") as String,
            userDocument.get("username") as String,
            userDocument.get("email") as String
    )
}