JasperFx / marten

.NET Transactional Document DB and Event Store on PostgreSQL
https://martendb.io
MIT License
2.79k stars 441 forks source link

Npgsql exception while using sync version of IEventsStore FetchStream #3180

Closed murlakatam closed 4 months ago

murlakatam commented 4 months ago

Marten 7.10.1

System.InvalidCastException: Reading as 'System.Collections.Generic.Dictionary2[[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Object, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]' is not supported for fields having DataTypeName 'jsonb' ---> System.NotSupportedException: Type 'Dictionary2' required dynamic JSON serialization, which requires an explicit opt-in; call 'EnableDynamicJson' on 'NpgsqlDataSourceBuilder' or NpgsqlConnection.GlobalTypeMapper (see https://www.npgsql.org/doc/types/json.html and the 8.0 release notes for more details). Alternatively, if you meant to use Newtonsoft JSON.NET instead of System.Text.Json, call UseJsonNet() instead.

at Npgsql.Internal.ResolverFactories.JsonDynamicTypeInfoResolverFactory.ThrowIfUnsupported[TBuilder](Type type, Nullable1 dataTypeName, PgSerializerOptions options) at Npgsql.Internal.ResolverFactories.UnsupportedTypeInfoResolver1.GetTypeInfo(Type type, Nullable1 dataTypeName, PgSerializerOptions options) at Npgsql.Internal.ChainTypeInfoResolver.GetTypeInfo(Type type, Nullable1 dataTypeName, PgSerializerOptions options) at Npgsql.Internal.TypeInfoCache1.<GetOrAddInfo>g__CreateInfo|6_3(Type type, Nullable1 typeId, PgSerializerOptions options, Boolean defaultTypeFallback, Boolean validatePgTypeIds) at Npgsql.Internal.TypeInfoCache1.<GetOrAddInfo>g__AddEntryById|6_2(Type type, TPgTypeId pgTypeId, ValueTuple2[] infos, Boolean defaultTypeFallback) at Npgsql.Internal.TypeInfoCache1.GetOrAddInfo(Type type, Nullable1 pgTypeId, Boolean defaultTypeFallback) at Npgsql.Internal.PgSerializerOptions.GetTypeInfoCore(Type type, Nullable1 pgTypeId, Boolean defaultTypeFallback) at Npgsql.Internal.PgSerializerOptions.GetTypeInfo(Type type, PostgresType pgType) at Npgsql.Internal.AdoSerializerHelpers.GetTypeInfoForReading(Type type, PostgresType postgresType, PgSerializerOptions options) --- End of inner exception stack trace --- at Npgsql.Internal.AdoSerializerHelpers.<GetTypeInfoForReading>g__ThrowReadingNotSupported|0_0(Type type, String displayName, Exception inner) at Npgsql.Internal.AdoSerializerHelpers.GetTypeInfoForReading(Type type, PostgresType postgresType, PgSerializerOptions options) at Npgsql.BackendMessages.FieldDescription.<GetInfo>g__GetInfoSlow|50_0(Type type, ColumnInfo& lastColumnInfo) at Npgsql.BackendMessages.FieldDescription.GetInfo(Type type, ColumnInfo& lastColumnInfo) at Npgsql.NpgsqlDataReader.<GetInfo>g__Slow|133_0(ColumnInfo& info, PgConverter& converter, Size& bufferRequirement, Boolean& asObject, <>c__DisplayClass133_0&) at Npgsql.NpgsqlDataReader.GetFieldValueCore[T](Int32 ordinal) at Npgsql.NpgsqlDataReader.GetFieldValue[T](Int32 ordinal) at Marten.Generated.EventStore.GeneratedEventDocumentStorage.ApplyReaderDataToEvent(DbDataReader reader, IEvent e) in ........\Internal\Generated\EventStore\EventStorage.cs:line 81 at Marten.Events.EventDocumentStorage.Resolve(DbDataReader reader) at Marten.Linq.QueryHandlers.ListQueryHandler1.Handle(DbDataReader reader, IMartenSession session) at Marten.Internal.Sessions.QuerySession.ExecuteHandler[T](IQueryHandler1 handler) at Marten.Events.QueryEventStore.FetchStream(String streamKey, Int64 version, Nullable1 timestamp, Int64 fromVersion)

when you call ((IDocumentSession)session).Events.FetchStream(streamId)

However calling async version of the same api produces no exceptions ((IDocumentSession)session).Events.FetchStreamAsync(streamId, token: cancellationToken)

        // events config
        options.Events.MetadataConfig.HeadersEnabled = true;
        options.Events.MetadataConfig.CausationIdEnabled = false;
        options.Events.MetadataConfig.CorrelationIdEnabled = true;

Generated code difference (EventStorage.cs): sync (where the bug is) image vs async (which works fine) image

Manually changing the sync version in generated code to

if (!reader.IsDBNull(10))
            {
            var headers = _options.Serializer().FromJson<System.Collections.Generic.Dictionary<string, object>>(reader, 10);
            e.Headers = headers;
            }

fixes the problem