private void encodeValue0(
            BsonWriter writer,
            T value,
            EncoderContext encoderContext,
            boolean writeNullValue) {
        for (EntityField<?> field : entity.fields()) {
            Object fieldValue = field.get(value);
            switch (field.type()) {
                case ID -> {
                    if (fieldValue == null) {
                        if (writeNullValue) {
                            writer.writeName(DomainFieldName.ID);
                            writer.writeNull();
                        }
                    } else {
                        writer.writeName(DomainFieldName.ID);
                        Codec codec = getCodec(field);
                        codec.encode(writer, fieldValue, encoderContext);
                    }
                }
                case USER_DEFINED_ATTRIBUTES -> {
                    Map<String, Object> userDefinedAttributes = (Map<String, Object>) fieldValue;
                    if (userDefinedAttributes == null) {
                        continue;
                    }
                    for (Map.Entry<String, Object> entry : userDefinedAttributes.entrySet()) {
                        Object entryValue = entry.getValue();
                        if (entryValue == null) {
                            if (writeNullValue) {
                                writer.writeName(USER_DEFINED_ATTRIBUTE_PREFIX + entry.getKey());
                                writer.writeNull();
                            }
                        } else {
                            writer.writeName(USER_DEFINED_ATTRIBUTE_PREFIX + entry.getKey());
                            CodecUtil.write(writer, entryValue);
                        }
                    }
                }
                case NORMAL -> {
                    if (fieldValue == null) {
                        if (writeNullValue) {
                            writer.writeName(field.name());
                            writer.writeNull();
                        }
                    } else {
                        writer.writeName(field.name());
                        Codec codec = getCodec(field);
                        codec.encode(writer, fieldValue, encoderContext);
                    }
                }
            }
        }
    }
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