title: How to save Java 8 Instant to MongoDB as Date type using Spring MongoTemplate?
body: <p>I have a Java class having an <code>Instant</code> type of member variable:</p>
  
  <pre><code>public class SomeRecord {
      private String someId;
  
      private Instant someInstant;
  
      // getters and setters
  }
  </code></pre>
  
  <p>I am using MongoTemplate to update the <code>someInstant</code> field in database:</p>
  
  <pre><code>public SomeRecord updateSomeRecordBySomeId(final String someId, Object someInstant) {
          Query query = new Query();
          query.addCriteria(Criteria.where("someId").is(someId));
  
          Update update = new Update();
          update.set("someInstant", someInstant);
  
          return operations.findAndModify(query, update, new FindAndModifyOptions().returnNew(true), SomeRecord.class);
  }
  </code></pre>
  
  <p>This works great if I am calling the method as:</p>
  
  <p><code>updateSomeRecordBySomeId("SOME-ID", Instant.now());</code>
  persisting the field in DB as a <code>Date</code> type:
  <code>"someInstant" : ISODate("2017-07-11T07:26:44.269Z")</code></p>
  
  <hr>
  
  <p>Now the method may also be called as:
  <code>updateSomeRecordBySomeId("SOME-ID", "2017-07-11T07:26:44.269Z");</code></p>
  
  <p>In this case I get an exception as:</p>
  
  <blockquote>
    <p>org.springframework.core.convert.ConverterNotFoundException: No
    converter found capable of converting from type [java.lang.String] to
    type [java.time.Instant]</p>
  </blockquote>
  
  <p>which makes complete sense. (It updates the field in the DB as <code>String</code> though. <code>"someInstant" : "2017-07-11T07:26:44.269Z"</code>)</p>
  
  <p><hr>
  So I added a converter as follows:</p>
  
  <p>MongoConfig.java:</p>
  
  <pre><code>@Configuration
  @ComponentScan(basePackages = {"dao package path here"})
  public class MongoConfig {
      @Autowired
      private MongoDbFactory mongoDbFactory;
  
      @Bean
      public MongoTemplate mongoTemplate() {
          MappingMongoConverter converter = new MappingMongoConverter(new DefaultDbRefResolver(mongoDbFactory),
                  new MongoMappingContext());
  
          converter.setCustomConversions(new CustomConversions(Collections.singletonList(new StringToInstantConverter())));
  
          return new MongoTemplate(mongoDbFactory, converter);
      }
  }
  </code></pre>
  
  <p>StringToInstantConverter.java:</p>
  
  <pre><code>public class StringToInstantConverter implements Converter&lt;String, Instant&gt; {
      @Override
      public Instant convert(String utcString) {
          // TODO: Make it generic for any time-zone
          return Instant.parse(utcString);
      }
  }
  </code></pre>
  
  <p>After adding the above converter I am not getting <code>ConverterNotFoundException</code> any longer, but the field <code>someInstant</code> is being persisted as plain string: <code>"someInstant" : "2017-07-11T07:26:44.269Z"</code></p>
  
  <p>And that's what my question is. I know that the converter is being identified that is the reason I am not getting the exception anymore. But why the converter is not converting the <code>String</code> to <code>Instant</code>? Why the field is being persisted as plain <code>String</code>? Is the converter supplied incorrect? How to write converter for this case?</p>
  
  <p>Note:</p>
  
  <ul>
  <li><p>I have simplified the code to focus on the actual problem. In actual the method does not receive the <code>someInstant</code> field as parameter. So writing overloaded method is not going to be applicable here. Also any kind of <code>instanceOf</code> check inside the method won't work for the actual scenario. So the focus is on the question why the conversion not happening?</p></li>
  <li><p>The actual data-store for us is DocumentDB, but we use <a href="https://docs.microsoft.com/en-us/azure/cosmos-db/create-mongodb-dotnet#create-account" rel="nofollow noreferrer">DocumentDB with MongoDB API</a>(as Spring Data does not support DocumentDB) for our database operations.</p></li>
  </ul>