code: private <T> MappedClass validateSave(final T entity) {
          if (entity == null) {
              throw new UpdateException("Can not persist a null entity");
          }
  
          final MappedClass mc = mapper.getMappedClass(entity);
          if (mc.getAnnotation(NotSaved.class) != null) {
              throw new MappingException(format("Entity type: %s is marked as NotSaved which means you should not try to save it!",
                  mc.getClazz().getName()));
          }
          return mc;
      }
docs: /*
  @SuppressWarnings("unchecked")
  private <T> Key<T> save(final MongoCollection collection, final T entity, final InsertOneOptions options) {
  final MappedClass mc = validateSave(entity);
  
  involvedObjects is used not only as a cache but also as a list of what needs to be called for life-cycle methods at the end.
  final LinkedHashMap<Object, DBObject> involvedObjects = new LinkedHashMap<Object, DBObject>();
  final Document document = new Document(entityToDBObj(entity, involvedObjects).toMap());
  
  try to do an update if there is a @Version field
  final Object idValue = document.get(Mapper.ID_KEY);
  UpdateResult wr = tryVersionedUpdate(collection, entity, document, idValue, options, mc);
  
  if (wr == null) {
  if (document.get(ID_FIELD_NAME) == null) {
  collection.insertOne(singletonList(document), options);
  } else {
  collection.updateOne(new Document(ID_FIELD_NAME, document.get(ID_FIELD_NAME)), document,
  new com.mongodb.client.model.UpdateOptions()
  .bypassDocumentValidation(options.getBypassDocumentValidation())
  .upsert(true));
  }
  }
  
  return postSaveOperations(singletonList(entity), involvedObjects, collection.getNamespace().getCollectionName()).get(0);
  }