Unknown discriminator value 'MyEvent'
Asked Answered
P

2

8

Using the MongoDB persistance engine in joliver/EventStore causing the error Unknown discriminator value 'MyEvent'. The issue is only caused when I try to load all events for replaying the events like this.storeEvent.Advanced.GetFrom(new DateTime(2010, 1,1))

The issues is caused in ExtensionsMethods.cs

public class MyClassEvent : IDomainEvent { ... }

public static Commit ToCommit(this BsonDocument doc, IDocumentSerializer serializer)
    {
        if (doc == null)
            return null;

        var id = doc["_id"].AsBsonDocument;
        var streamId = id["StreamId"].AsGuid;
        var commitSequence = id["CommitSequence"].AsInt32;

        var events = doc["Events"].AsBsonArray.Select(e => e.AsBsonDocument["Payload"].IsBsonDocument ? BsonSerializer.Deserialize<EventMessage>(e.AsBsonDocument["Payload"].AsBsonDocument) : serializer.Deserialize<EventMessage>(e.AsBsonDocument["Payload"].AsByteArray)).ToList();
        var streamRevision = doc["Events"].AsBsonArray.Last().AsBsonDocument["StreamRevision"].AsInt32;
        return new Commit(
            streamId,
            streamRevision,
            doc["CommitId"].AsGuid,
            commitSequence,
            doc["CommitStamp"].AsDateTime,
            BsonSerializer.Deserialize<Dictionary<string, object>>(doc["Headers"].AsBsonDocument),
            events);
    }

My configuration is like this:

 Wireup.Init()                
            .UsingMongoPersistence(connectionName, new DocumentObjectSerializer())
            .UsingBsonSerialization()    
            .UsingAsynchronousDispatcher()                                
            .PublishTo(this.container.Resolve<IPublishMessages>())
            .Build();

But have tried almost all kind of serializer options.

Pancratium answered 16/9, 2011 at 23:43 Comment(0)
N
10

Try to register your objects (itself the event messages as well as the subjects of the EventStore payloads) using the BsonClassMap.RegisterClassMap method. It seems EventStore's mongo extension handles the string payloads well, but not the deserialized objects ... at least registering the classed was the solution in my case.

Narrate answered 17/9, 2011 at 12:44 Comment(2)
Thank you. When i saved the commits, the mongo db driver registered the classes itself, however on reply (pure reading) the mapping was not done.Pancratium
Thanks, although I can't see why this should be necessarySeadon
F
15

I just ran into this too. Zsolt's answer was a good starting point, but I ended up solving it slightly different.

Note that I did not only get this when myEventStore.Advanced.GetFrom(...); myEventStore.OpenStream(...) also fails. This makes sense, because both methods use the same IPersistentStream and serializer.

I don't run into this problem when when I first persist an event, before retrieving an event of the same type. Apparently MongoDB creates a ClassMap when it's being asked to serialize a type for the first time.

Anyway, for me the solution was to create a class map for all my event types on application startup. Assuming all type are in the assembly of SimpleCQRS.Event and derive from SimpleCQRS.Event, I do it like this:

var types = Assembly.GetAssembly(typeof(SimpleCQRS.Event))
                    .GetTypes()
                    .Where(type => type.IsSubclassOf(typeof(SimpleCQRS.Event)));
foreach (var t in types)
    BsonClassMap.LookupClassMap(t);

For me this works better than using BsonClassMap.RegisterClassMap<TypeToMap> like Zsolt suggests, because that requires a generic type parameter, meaning you have to manually add each event type.

Firstfoot answered 31/7, 2012 at 15:12 Comment(1)
Excellent futureproofing idea, with just some small fine print / caveat that a) all SimpleCQRS.Event subclasses will be added indiscriminately, and that b) that all of the Known Type subclasses must reside in the same assembly.Xymenes
N
10

Try to register your objects (itself the event messages as well as the subjects of the EventStore payloads) using the BsonClassMap.RegisterClassMap method. It seems EventStore's mongo extension handles the string payloads well, but not the deserialized objects ... at least registering the classed was the solution in my case.

Narrate answered 17/9, 2011 at 12:44 Comment(2)
Thank you. When i saved the commits, the mongo db driver registered the classes itself, however on reply (pure reading) the mapping was not done.Pancratium
Thanks, although I can't see why this should be necessarySeadon

© 2022 - 2024 — McMap. All rights reserved.