Skip to content

NullRefException when trying to serialize/deserialize a null navigational property of a migrated entity #84

@BoutemineOualid

Description

@BoutemineOualid

Describe the bug
When trying to execute a lookup query to load navigational properties of a migrated entity, the query fails with a null ref exception.

This happens at this line:

value.Version = _context.Option.CurrentVersion;

To Reproduce
Steps to reproduce the behavior:

  1. Create an entity E1 with a Migration
  2. Create another entity E2 that references E1 using a property E2.NavigationalProperty of type E1 and tag it with [BsonIgnoreIfNull]
  3. Create an instance of E2 and set E2.NavigationalProperty to null
  4. Persist it.
  5. Load the collection using an aggregate lookup/unwind

public class E1 : IEquatable<E1>, IVersioned
{
	[BsonId]
	public ObjectId Id { get; set; }

        ....

	public int Version { get; set; }
}


public class E2 : IEquatable<E2>, IVersioned
{
	[BsonId]
	public ObjectId Id { get; set; }
 
        [BsonElement("e1id")]
        public ObjectId E1Id { get; set; }

        [BsonIgnoreIfNull]
        public E1? NavigationalProperty { get; set; }

	public int Version { get; set; }

 .....
}

public class E1Migration : IMigration
{
    public int Version => 1;
    
    public void Up(BsonDocument document)
    {
        document["newField"] = new BsonArray();
    }

    public void Down(BsonDocument document)
    {
        document.Remove("newField");
    }
}

_e2collection
            .Aggregate()
            .Lookup("E1Collection", nameof(E2.E1Id), "_id", nameof(E2.NavigationalProperty))
            .Unwind(nameof(E2.NavigationalProperty))
            .As<E2>()
           .Match(_ => true)
           .ToListAsync(ct)
  1. Notice a null ref exception is triggered when trying to materialize the result.

Expected behavior
Null values should not be serialized/deserialized if they are marked as [BsonIgnoreIfNull]. Bellow is the stack trace.

Stack Trace

System.NullReferenceException: Object reference not set to an instance of an object.
   at MongoDB.Extensions.Migration.MigrationSerializer`1.Serialize(BsonSerializationContext context, BsonSerializationArgs args, T value)
   at MongoDB.Bson.Serialization.Serializers.SerializerBase`1.MongoDB.Bson.Serialization.IBsonSerializer.Serialize(BsonSerializationContext context, BsonSerializationArgs args, Object value)
   at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Serialize(IBsonSerializer serializer, BsonSerializationContext context, Object value)
   at MongoDB.Bson.Serialization.IBsonSerializerExtensions.ToBsonValue(IBsonSerializer serializer, Object value)
   at MongoDB.Driver.Linq.Linq2Implementation.Translators.PredicateTranslator.TranslateComparison(Expression variableExpression, ExpressionType operatorType, ConstantExpression constantExpression)
   at MongoDB.Driver.Linq.Linq2Implementation.Translators.PredicateTranslator.TranslateComparison(BinaryExpression binaryExpression)
   at MongoDB.Driver.Linq.Linq2Implementation.Translators.PredicateTranslator.Translate(Expression node)
   at MongoDB.Driver.Linq.Linq2Implementation.Translators.PredicateTranslator.TranslateAndAlso(BinaryExpression node)
   at MongoDB.Driver.Linq.Linq2Implementation.Translators.PredicateTranslator.Translate(Expression node)
   at MongoDB.Driver.Linq.Linq2Implementation.Translators.PredicateTranslator.TranslateAndAlso(BinaryExpression node)
   at MongoDB.Driver.Linq.Linq2Implementation.Translators.PredicateTranslator.Translate(Expression node)
   at MongoDB.Driver.Linq.Linq2Implementation.Translators.PredicateTranslator.Translate(Expression node, IBsonSerializerRegistry serializerRegistry)
   at MongoDB.Driver.Linq.Linq2Implementation.Translators.PredicateTranslator.Translate[TDocument](Expression`1 predicate, IBsonSerializer`1 parameterSerializer, IBsonSerializerRegistry serializerRegistry)
   at MongoDB.Driver.Linq.Linq2Implementation.LinqProviderAdapterV2.TranslateExpressionToFilter[TDocument](Expression`1 expression, IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry)
   at MongoDB.Driver.ExpressionFilterDefinition`1.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry, LinqProvider linqProvider)
   at MongoDB.Driver.PipelineStageDefinitionBuilder.<>c__DisplayClass34_0`1.<Match>b__0(IBsonSerializer`1 s, IBsonSerializerRegistry sr, LinqProvider linqProvider)
   at MongoDB.Driver.DelegatedPipelineStageDefinition`2.Render(IBsonSerializer`1 inputSerializer, IBsonSerializerRegistry serializerRegistry, LinqProvider linqProvider)
   at MongoDB.Driver.AppendedStagePipelineDefinition`3.Render(IBsonSerializer`1 inputSerializer, IBsonSerializerRegistry serializerRegistry, LinqProvider linqProvider)
   at MongoDB.Driver.MongoCollectionImpl`1.AggregateAsync[TResult](IClientSessionHandle session, PipelineDefinition`2 pipeline, AggregateOptions options, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSessionAsync[TResult](Func`2 funcAsync, CancellationToken cancellationToken)
   at MongoDB.Driver.IAsyncCursorSourceExtensions.ToListAsync[TDocument](IAsyncCursorSource`1 source, CancellationToken cancellationToken)

Desktop (please complete the following information):

  • OS: MacOS/Linux/Windows
  • Version : 3.0.0

Additional context
Add any other context about the problem here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions