Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unknown discriminator value 'MyEvent'

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.

like image 813
Jacee Avatar asked Sep 16 '11 23:09

Jacee


2 Answers

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.

like image 148
Marijn Avatar answered Sep 18 '22 22:09

Marijn


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.

like image 25
Zsolt Pardi Avatar answered Sep 16 '22 22:09

Zsolt Pardi