public <T> UpdateResults<T> updateFirst(Query<T> query, T entity, boolean createIfMissing) {
    LinkedHashMap<Object, DBObject> involvedObjects = new LinkedHashMap<Object, DBObject>();
    DBObject dbObj = mapr.toDBObject(entity, involvedObjects);

    UpdateResults<T> res = update(query, dbObj, createIfMissing, false, getWriteConcern(entity));

    // update _id field
    CommandResult gle = res.getWriteResult().getCachedLastError();
    if (gle != null && res.getInsertedCount() > 0) dbObj.put(Mapper.ID_KEY, res.getNewId());

    postSaveOperations(entity, dbObj, involvedObjects);
    return res;
  }
  public <T> Key<T> merge(T entity, WriteConcern wc) {
    LinkedHashMap<Object, DBObject> involvedObjects = new LinkedHashMap<Object, DBObject>();
    DBObject dbObj = mapr.toDBObject(entity, involvedObjects);
    Key<T> key = getKey(entity);
    entity = ProxyHelper.unwrap(entity);
    Object id = getId(entity);
    if (id == null)
      throw new MappingException("Could not get id for " + entity.getClass().getName());
    Query<T> query = (Query<T>) createQuery(entity.getClass()).filter(Mapper.ID_KEY, id);

    // remove (immutable) _id field for update.
    dbObj.removeField(Mapper.ID_KEY);
    UpdateResults<T> res = update(query, new BasicDBObject("$set", dbObj), false, false, wc);

    // check for updated count if we have a gle
    CommandResult gle = res.getWriteResult().getCachedLastError();
    if (gle != null && res.getUpdatedCount() == 0) throw new UpdateException("Not updated: " + gle);

    postSaveOperations(entity, dbObj, involvedObjects);
    return key;
  }
  protected <T> WriteResult tryVersionedUpdate(
      DBCollection dbColl, T entity, DBObject dbObj, WriteConcern wc, DB db, MappedClass mc) {
    WriteResult wr = null;
    if (mc.getFieldsAnnotatedWith(Version.class).isEmpty()) return wr;

    MappedField mfVersion = mc.getFieldsAnnotatedWith(Version.class).get(0);
    String versionKeyName = mfVersion.getNameToStore();
    Long oldVersion = (Long) mfVersion.getFieldValue(entity);
    long newVersion = VersionHelper.nextValue(oldVersion);
    dbObj.put(versionKeyName, newVersion);
    if (oldVersion != null && oldVersion > 0) {
      Object idValue = dbObj.get(Mapper.ID_KEY);

      UpdateResults<T> res =
          update(
              find((Class<T>) entity.getClass(), Mapper.ID_KEY, idValue)
                  .filter(versionKeyName, oldVersion),
              dbObj,
              false,
              false,
              wc);

      wr = res.getWriteResult();

      if (res.getUpdatedCount() != 1)
        throw new ConcurrentModificationException(
            "Entity of class "
                + entity.getClass().getName()
                + " (id='"
                + idValue
                + "',version='"
                + oldVersion
                + "') was concurrently updated.");
    } else if (wc == null) wr = dbColl.save(dbObj);
    else wr = dbColl.save(dbObj, wc);

    // update the version.
    mfVersion.setFieldValue(entity, newVersion);
    return wr;
  }