FindOneAndUpdate should insert correct discriminator value on upsert

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Fixed
    • Priority: Unknown
    • 3.5.0
    • Affects Version/s: 3.4.0
    • Component/s: None
    • None
    • None
    • Fully Compatible
    • Dotnet Drivers
    • Not Needed
    • None
    • None
    • None
    • None
    • None
    • None

      Summary

      Upsert with FindOneAndUpdateAsync does not set correct discriminator for hierarcal documents. It does correctly work with UpdateOneAsync. FindOneAndUpdateAsync created document has a string discriminator when it should be an array with hierarchical types.

       

       

      Driver version: 3.4

      topology: standalone

      How to Reproduce

      Example console application:

       

      
      

      _using MongoDB.Bson;
      using MongoDB.Bson.Serialization;
      using MongoDB.Bson.Serialization.Attributes;
      using MongoDB.Bson.Serialization.Serializers;
      using MongoDB.Driver;
      using MongoDB.Driver.Core.Events;

      BsonSerializer.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard));

      BsonClassMap.RegisterClassMap<Animal>();
      BsonClassMap.RegisterClassMap<Cat>();
      BsonClassMap.RegisterClassMap<Dog>();
      BsonClassMap.RegisterClassMap<Lion>();
      BsonClassMap.RegisterClassMap<Tiger>();

      var connectionString = "mongodb://localhost/db?directConnection=true";
      var settings = MongoClientSettings.FromUrl(new MongoUrl(connectionString));

      settings.ClusterConfigurator = builder =>
      {
      builder.Subscribe<CommandStartedEvent>(e =>
      {
      Console.WriteLine($"Command

      {e.CommandName}

      -> {e.Command.ToJson()}");
      });
      };
      var client = new MongoClient(settings);

      // Bootstrap data
      var collection = client.GetDatabase("db").GetCollection<Animal>("animals");
      var lion1 = new Lion()
      {
      Id = Guid.NewGuid(), Name = "Lion1"

      };

      var updateDefinition1 = Builders<Lion>.Update
      .SetOnInsert(l=>l.Id, lion1.Id)
      .Set(l => l.Name, lion1.Name);

      await collection.OfType<Lion>().FindOneAndUpdateAsync(f=>f.Name == lion1.Name,updateDefinition1, new FindOneAndUpdateOptions<Lion>{ IsUpsert = true });

      var lion2 = new Lion()
      {
      Id = Guid.NewGuid(), Name = "Lion2"

      };
      var updateDefinition2 = Builders<Lion>.Update
      .SetOnInsert(l=>l.Id, lion2.Id)
      .Set(l => l.Name, lion2.Name);

      await collection.OfType<Lion>().UpdateOneAsync(f=>f.Name == lion2.Name,updateDefinition2, new UpdateOptions{ IsUpsert = true });

      var cats = (await collection.OfType<Cat>().FindAsync(f=> true)).ToList();
      var catCount = cats.Count;
      //catCount is 1, should be 2
      //Contains only the document inserted via UpdateOneAsync, does not contain inserted via FindOneAndUpdateAsync

      /*
      *{
      "_id" : UUID("abd81744-fdd3-4dd2-9ac0-9af43c824fdf"),
      "Name" : "Lion1",
      "_t" : "Lion"
      }
      {
      "_id" : UUID("7bb7b4b1-7559-4a9f-9f58-c27a5072c53f"),
      "Name" : "Lion2",
      "_t" : [
      "Animal",
      "Cat",
      "Lion"
      ]
      }
      */

      [BsonDiscriminator(RootClass = true)]
      [BsonKnownTypes(typeof(Cat), typeof(Dog))]
      public class Animal
      {
      public Guid Id

      { get; set; }
      }_
      [BsonKnownTypes(typeof(Lion), typeof(Tiger))]
      _public class Cat : Animal
      {
      }
      public class Dog : Animal
      {
      }
      public class Lion : Cat
      {
      public string Name { get; set; }

      }
      public class Tiger : Cat
      {
      }_

      Actual Result:

       

      {
          "_id" : UUID("abd81744-fdd3-4dd2-9ac0-9af43c824fdf"),
          "Name" : "Lion1",
          "_t" : "Lion"
      }
      {
          "_id" : UUID("7bb7b4b1-7559-4a9f-9f58-c27a5072c53f"),
          "Name" : "Lion2",
          "_t" : [
              "Animal",
              "Cat",
              "Lion"
          ]
      } 

      Expected result:

      {
          "_id" : UUID("abd81744-fdd3-4dd2-9ac0-9af43c824fdf"),
          "Name" : "Lion1",  
          "_t" : [ 
               "Animal",
               "Cat",
               "Lion" 
           ]
       }
      {
          "_id" : UUID("7bb7b4b1-7559-4a9f-9f58-c27a5072c53f"),
          "Name" : "Lion2",
          "_t" : [
              "Animal",
              "Cat",
              "Lion"
          ]
      }
      
      
      

            Assignee:
            Robert Stam
            Reporter:
            donatas vizgirda
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: