private <F> Codec<F> getCodec(EntityField<F> field) {
        Class<?> fieldClass = field.fieldClass();
        if (Iterable.class.isAssignableFrom(fieldClass)) {
            return (Codec<F>) KEY_TO_ITERABLE_CODEC.computeIfAbsent(
                    new IterableCodecKey<>(fieldClass, field.elementClass(), field.isEnumNumber()),
                    key -> {
                        TurmsIterableCodec<?, ?> iterableCodec = new TurmsIterableCodec<>(
                                key.iterableClass,
                                key.elementClass,
                                key.isEnumNumber);
                        iterableCodec.setRegistry(registry);
                        return iterableCodec;
                    });
        } else if (Map.class.isAssignableFrom(fieldClass)) {
            return (Codec<F>) KEY_TO_MAP_CODEC.computeIfAbsent(new MapCodecKey<>(
                    (Class) fieldClass,
                    field.keyClass(),
                    field.elementClass(),
                    field.isEnumNumber()), key -> {
                        TurmsMapCodec<?, ?> mapCodec = new TurmsMapCodec(
                                key.ownerClass,
                                key.keyClass,
                                key.valueClass,
                                key.isEnumNumber);
                        mapCodec.setRegistry(registry);
                        return mapCodec;
                    });
        } else if (fieldClass.isEnum()) {
            return (Codec<F>) KEY_TO_ENUM_CODEC.computeIfAbsent(
                    new EnumCodecKey<>(fieldClass, field.isEnumNumber()),
                    key -> key.isEnumNumber
                            ? new EnumNumberCodec<>((Class) key.fieldClass)
                            : new EnumStringCodec<>((Class) key.fieldClass));
        } else {
            if (fieldClass.isPrimitive()) {
                fieldClass = PrimitiveUtil.primitiveToWrapper(fieldClass);
            }
            return (Codec<F>) registry.get(fieldClass);
        }
    }
Compared to {@link EntityCodec#encodeValue}, this method encodes null fields because we need
to overwrite existing fields to null if these fields are not specified in the entity for our
use cases.
turms-server-common/src/main/java/im/turms/server/common/storage/mongo/codec/EntityCodec.java