class AbstractMongoDao extends AbstractDao<M,P,K,I> {

    @Override
    public M create(P partial, Instant createAt, I createBy) {
        Document doc = partialMapper.toDocument(partial);
        if (doc.get(ID_FIELD) == null) {
            doc.put(ID_FIELD, generateId());
        }
        FieldData fieldData = getFieldData();
        if (createAt != null && fieldData.getCreatedAt() != null
                && doc.get(fieldData.getCreatedAt().getStorageName()) == null) {
            doc.put(fieldData.getCreatedAt().getStorageName(), Date.from(createAt));
        }
        if (createBy != null && fieldData.getCreatedBy() != null
                && doc.get(fieldData.getCreatedBy().getStorageName()) == null) {
            doc.put(fieldData.getCreatedBy().getStorageName(), createBy);
        }
        // automatically pre-populate updatedAt/updatedBy, if those fields are non-optional
        if (createAt != null && fieldData.getUpdatedAt() != null
                && !fieldData.getUpdatedAt().isOptional()
                && doc.get(fieldData.getUpdatedAt().getStorageName()) == null) {
            doc.put(fieldData.getUpdatedAt().getStorageName(), Date.from(createAt));
        }
        if (createBy != null && fieldData.getUpdatedBy() != null
                && !fieldData.getUpdatedBy().isOptional()
                && doc.get(fieldData.getUpdatedBy().getStorageName()) == null) {
            doc.put(fieldData.getUpdatedBy().getStorageName(), createBy);
        }
        M model = modelMapper.toObject(doc);
        getCollection().insertOne(doc);
        return model;
    }

    public  AbstractMongoDao(Class<M> modelClass, Class<P> partialClass, MongoCollection<Document> collection);
    public  AbstractMongoDao(Class<M> modelClass, Class<P> partialClass, MongoCollection<Document> collection, ObjectMapper objectMapper, ObjectMapper extendedJsonMapper);
    public  AbstractMongoDao(Class<M> modelClass, Class<P> partialClass, MongoCollection<Document> collection,
                            DocumentMapper<M> modelMapper, DocumentMapper<P> partialMapper);

}