title: How do I properly extend Mongo's Document class?
body: <p>I've created a class <code>User</code> that extends <code>Document</code>. <code>User</code> just has some simple constructors and getters/setters around some strings and ints. However, when I try to insert the User class into Mongo I get the following error:</p>
  
  <pre><code>Exception in thread "main" org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class com.foo.User.
      at org.bson.codecs.configuration.CodecCache.getOrThrow(CodecCache.java:46)
      at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:63)
      at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:37)
      at org.bson.BsonDocumentWrapper.asBsonDocument(BsonDocumentWrapper.java:62)
      at com.mongodb.MongoCollectionImpl.documentToBsonDocument(MongoCollectionImpl.java:507)
      at com.mongodb.MongoCollectionImpl.insertMany(MongoCollectionImpl.java:292)
      at com.mongodb.MongoCollectionImpl.insertMany(MongoCollectionImpl.java:282)
      at com.foo.bar.main(bar.java:27)
  </code></pre>
  
  <p>Sounds like I need to work with some Mongo Codecs stuff, but I'm not familiar with it and some quick googling returns some results that seem pretty advanced.</p>
  
  <p>How do I properly write my <code>User</code> class for use in Mongo? Here is my class for reference:</p>
  
  <pre><code>public class User extends Document {
      User(String user, List&lt;Document &gt; history, boolean isActive, String location){
          this.append("_id", user)
                  .append("history", history)
                  .append("isActive", isActive)
                  .append("location", location);
      }
  
      public List&lt;Document &gt; getHistory(){
          return this.get("history", ArrayList.class);
      }
  
      public void addToHistory(Document event){
         List&lt;Document&gt; history = this.getHistory();
          history.add(event);
          this.append("history", history);
      }
  
      public boolean hasMet(User otherUser){
          List&lt;String&gt; usersIveMet = this.getUsersMet(),
                       usersTheyMet = otherUser.getUsersMet();
          return !Collections.disjoint(usersIveMet, usersTheyMet);
      }
  
      public List&lt;String&gt; getUsersMet() {
          List&lt;Document&gt; usersHistory = this.getHistory();
          List&lt;String&gt; usersMet = usersHistory.stream()
                  .map(doc -&gt; Arrays.asList(doc.getString("user1"), doc.getString("user1")))
                  .filter(u -&gt; !u.equals(this.getUser()))
                  .flatMap(u -&gt; u.stream())
                  .collect(Collectors.toList());
          return usersMet;
      }
  
      public String getUser(){
          return this.getString("_id");
      }
  }
  </code></pre>