ryanheath / RavenDB-NodaTime

Noda Time support for RavenDB
Other
20 stars 14 forks source link

Conventions has frozen after 'DocumentStore.Initialize()' and no changes can be applied to them. #21

Closed Leon99 closed 4 years ago

Leon99 commented 5 years ago

I'm getting this exception:

System.InvalidOperationException
  HResult=0x80131509
  Message=Conventions has frozen after 'DocumentStore.Initialize()' and no changes can be applied to them.
  Source=Raven.Client
  StackTrace:
   at Raven.Client.Documents.Conventions.DocumentConventions.AssertNotFrozen() in C:\Builds\RavenDB-Stable-4.2\42018\src\Raven.Client\Documents\Conventions\DocumentConventions.cs:line 1115
   at Raven.Client.NodaTime.Extensions.ConfigureForNodaTime[T](T documentStore, IDateTimeZoneProvider zoneProvider)

Code:

var server = EmbeddedServer.Instance;
server.StartServer();
var documentStore = server.GetDocumentStore(new DatabaseOptions("Embedded"));
documentStore.Initialize();
documentStore.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);

Moving ConfigureForNodaTime() before Initialize() produces the same exception.

Any ideas appreciated.

Leon99 commented 5 years ago

It looks like the embedded server does document store init implicitly so it's getting locked right after GetDocumentStore(). I managed to get past the exception by leveraging the code from ConfigureForNodaTime() and adding a converter (I only needed LocalDate)/calling RegisterQueryValueConverter() on DatabaseOptions. I also had to copy CustomQueryValueConverters as it's marked as internal.

My questions so far:

  1. Does that mean that the package currently doesn't support the embedded server?
  2. What about the non-embedded version, does it not freeze the conventions on Initialize()?
  3. Even after I did the configuration via DatabaseOptions, on deserialization from the DB I had string instead of LocalDate - is that expected? I suspect it's caused by using IDictionary<string, object> for the field that was the deserialization target - if so, are there any workarounds to get boxed LocalDate instead of string?
Leon99 commented 5 years ago

According to https://ravendb.net/docs/article-page/4.2/csharp/client-api/creating-document-store,

The Document Store is immutable - all above configuration are frozen upon calling .Initialize().

Does that mean that https://github.com/ryanheath/RavenDB-NodaTime/wiki/Installation-and-Configuration is incorrect (outdated)?

ryanheath commented 5 years ago

Calling documentStore.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb); before the Initialize should work, as that is what we are doing within the unit tests see MyRavenTestDriver.cs and RavenTestDriver.cs

As far as I can see, it looks like the test driver is not using the embedded documentstore for the client, but it creates a client separately, see

For your question about the deserialization of LocalDate into string, do you have a project I can take a look at?

ryanheath commented 5 years ago

I have update the wiki to reflect the 4.x initialization order.

Kibnet commented 4 years ago

I found workaround!

var dbOptions = new DatabaseOptions(dbRecord);
var store = new DocumentStore{Conventions = dbOptions.Conventions};
store.ConfigureForNodaTime();
Kibnet commented 4 years ago

I created pull request