private TypeConverter getEncoder(Object val, MappedField mf) {

    List<TypeConverter> tcs = null;

    if (val != null) tcs = tcMap.get(val.getClass());

    if (tcs == null || (tcs.size() > 0 && tcs.get(0) instanceof PassthroughConverter))
      tcs = tcMap.get(mf.getType());

    if (tcs != null) {
      if (tcs.size() > 1)
        log.warning(
            "Duplicate converter for " + mf.getType() + ", returning first one from " + tcs);
      return tcs.get(0);
    }

    for (TypeConverter tc : untypedTypeEncoders)
      if (tc.canHandle(mf) || (val != null && tc.isSupported(val.getClass(), mf))) return tc;

    throw new ConverterNotFoundException(
        "Cannot find encoder for " + mf.getType() + " as need for " + mf.getFullName());
  }
 public void fromDBObject(final DBObject dbObj, final MappedField mf, final Object targetEntity) {
   Object object = mf.getDbObjectValue(dbObj);
   if (object == null) {
     processMissingField(mf);
   } else {
     TypeConverter enc = getEncoder(mf);
     Object decodedValue = enc.decode(mf.getType(), object, mf);
     try {
       mf.setFieldValue(targetEntity, decodedValue);
     } catch (IllegalArgumentException e) {
       throw new MappingException(
           "Error setting value from converter ("
               + enc.getClass().getSimpleName()
               + ") for "
               + mf.getFullName()
               + " to "
               + decodedValue);
     }
   }
 }
  protected void ensureIndexes(
      MappedClass mc,
      boolean background,
      ArrayList<MappedClass> parentMCs,
      ArrayList<MappedField> parentMFs) {
    if (parentMCs.contains(mc)) return;

    // skip embedded types
    if (mc.getEmbeddedAnnotation() != null && (parentMCs == null || parentMCs.isEmpty())) return;

    // Ensure indexes from class annotation
    Indexes idxs = (Indexes) mc.getAnnotation(Indexes.class);
    if (idxs != null && idxs.value() != null && idxs.value().length > 0)
      for (Index index : idxs.value()) {
        BasicDBObject fields = QueryImpl.parseSortString(index.value());
        ensureIndex(
            mc.getClazz(),
            index.name(),
            fields,
            index.unique(),
            index.dropDups(),
            index.background() ? index.background() : background,
            index.sparse() ? index.sparse() : false);
      }

    // Ensure indexes from field annotations, and embedded entities
    for (MappedField mf : mc.getPersistenceFields()) {
      if (mf.hasAnnotation(Indexed.class)) {
        Indexed index = mf.getAnnotation(Indexed.class);
        StringBuilder field = new StringBuilder();
        Class<?> indexedClass = (parentMCs.isEmpty() ? mc : parentMCs.get(0)).getClazz();
        if (!parentMCs.isEmpty())
          for (MappedField pmf : parentMFs) field.append(pmf.getNameToStore()).append(".");

        field.append(mf.getNameToStore());

        ensureIndex(
            indexedClass,
            index.name(),
            new BasicDBObject(field.toString(), index.value().toIndexValue()),
            index.unique(),
            index.dropDups(),
            index.background() ? index.background() : background,
            index.sparse() ? index.sparse() : false);
      }

      if (!mf.isTypeMongoCompatible()
          && !mf.hasAnnotation(Reference.class)
          && !mf.hasAnnotation(Serialized.class)) {
        ArrayList<MappedClass> newParentClasses = (ArrayList<MappedClass>) parentMCs.clone();
        ArrayList<MappedField> newParents = (ArrayList<MappedField>) parentMFs.clone();
        newParentClasses.add(mc);
        newParents.add(mf);
        ensureIndexes(
            mapr.getMappedClass(mf.isSingleValue() ? mf.getType() : mf.getSubClass()),
            background,
            newParentClasses,
            newParents);
      }
    }
  }