Uploaded image for project: 'C# Driver'
  1. C# Driver
  2. CSHARP-2276

IMongoIndexManager CreateOne or CreateOneAsync methods can throw NullReferenceException

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 2.7.0
    • Affects Version/s: 2.7.0
    • Component/s: None
    • Labels:
      None
    • Environment:
      Windows 10 64-bit, MongoDB 3.7.9, .NET Core 2.1 RC 1

      Calling the IMongoIndexManager CreateOne or CreateOneAsync methods and omitting the options argument (or passing null for it) result in a NullReferenceException.

      *+Original description+:*

      I am using the C# driver 2.7.0-beta0001 and MongoDB 3.7.9 server and I am trying to create multiple indexes on a standalone server using the new transaction feature and I always get an exception:

       

      Message "Object reference not set to an instance of an object."
      
      Source  "MongoDB.Driver"
      
      StackTrace  "at MongoDB.Driver.MongoIndexManagerBase`1.ToCreateManyIndexesOptions(CreateOneIndexOptions options)
      at MongoDB.Driver.MongoIndexManagerBase`1.CreateOneAsync(IClientSessionHandle session, CreateIndexModel`1 model, CreateOneIndexOptions options, CancellationToken cancellationToken)
      
      TargetSite  {MongoDB.Driver.CreateManyIndexesOptions ToCreateManyIndexesOptions(MongoDB.Driver.CreateOneIndexOptions)}  System.Reflection.MethodBase {System.Reflection.RuntimeMethodInfo}
      
      {System.NullReferenceException: Object reference not set to an instance of an object.
      at MongoDB.Driver.MongoIndexManagerBase`1.ToCreateManyIndexesOptions(CreateOneIndexOptions options)
      at MongoDB.Driver.MongoIndexManagerBase`1.CreateOneAsync(IClientSessionHandle session, CreateIndexModel`1 model, CreateOneIndexOptions options, CancellationToken cancellationToken)
      

       

      Here is my code:

      var client = new MongoClient(ConnectionString);
      
      var database = client.GetDatabase(DatabaseName);
      
      var Coupons = database.GetCollection<Coupon>("Coupons");
      
      var Books = database.GetCollection<Book>("Books");
      
      var session = await database.Client.StartSessionAsync();
      session.StartTransaction();
      
      try {
      
           var options = new CreateIndexOptions() { Unique = true };
      
           var couponIndex = new IndexKeysDefinitionBuilder<Coupon>().Ascending(c => c.CouponNumber);
           var couponIndexModel = new CreateIndexModel<Coupon>(couponIndex, options);
           await Coupons.Indexes.CreateOneAsync(session, couponIndexModel);//Exception happens at this line
      
           var bookIndex = new IndexKeysDefinitionBuilder<Book>().Ascending(c => c.BookNumber);
           var bookIndexModel = new CreateIndexModel<Book>(bookIndex, options);
           await Books.Indexes.CreateOneAsync(session, bookIndexModel);
      
           await session.CommitTransactionAsync();
      } catch (Exception ex) {
           await session.AbortTransactionAsync();
      
           Console.WriteLine(ex.StackTrace);
      }
      

      Even if I didn't use the transactions by removing the session variable, I also get the same exception.

      If I used the old deprecated method like in this code I get a different exception:

      var couponsIndex = Builders<Coupon>.IndexKeys.Ascending(c => c.CouponNumber);                await Coupons.Indexes.CreateOneAsync(session, couponsIndex, options);
      

      Here is the other exception:

      {MongoDB.Driver.MongoCommandException: Command createIndexes failed: Transaction numbers are only allowed on a replica set member or mongos.
         at MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1.ProcessResponse(ConnectionId connectionId, CommandMessage responseMessage)
         at MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1.ExecuteAsync(IConnection connection, CancellationToken cancellationToken)
         at MongoDB.Driver.Core.Servers.Server.ServerChannel.ExecuteProtocolAsync[TResult](IWireProtocol`1 protocol, CancellationToken cancellationToken)
         at MongoDB.Driver.Core.Operations.CommandOperationBase`1.ExecuteProtocolAsync(IChannelSource channelSource, ICoreSessionHandle session, ReadPreference readPreference, CancellationToken cancellationToken)
         at MongoDB.Driver.Core.Operations.WriteCommandOperation`1.ExecuteAsync(IWriteBinding binding, CancellationToken cancellationToken)
         at MongoDB.Driver.Core.Operations.CreateIndexesUsingCommandOperation.ExecuteAsync(IWriteBinding binding, CancellationToken cancellationToken)
         at MongoDB.Driver.Core.Operations.CreateIndexesOperation.ExecuteAsync(IWriteBinding binding, CancellationToken cancellationToken)
         at MongoDB.Driver.OperationExecutor.ExecuteWriteOperationAsync[TResult](IWriteBinding binding, IWriteOperation`1 operation, CancellationToken cancellationToken)
         at MongoDB.Driver.MongoCollectionImpl`1.ExecuteWriteOperationAsync[TResult](IClientSessionHandle session, IWriteOperation`1 operation, CancellationToken cancellationToken)
         at MongoDB.Driver.MongoCollectionImpl`1.MongoIndexManager.CreateManyAsync(IClientSessionHandle session, IEnumerable`1 models, CreateManyIndexesOptions options, CancellationToken cancellationToken)
         at MongoDB.Driver.MongoIndexManagerBase`1.CreateOneAsync(IClientSessionHandle session, IndexKeysDefinition`1 keys, CreateIndexOptions options, CancellationToken cancellationToken)
      

       

            Assignee:
            robert@mongodb.com Robert Stam
            Reporter:
            MCoder Mohammed Abdel Gader Ibrahim ElAmin [X]
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: