[CSHARP-3186] Regression upgrading driver from 2.7 to 2.11 Created: 14/Aug/20 Updated: 27/Oct/23 Resolved: 29/Sep/20 |
|
| Status: | Closed |
| Project: | C# Driver |
| Component/s: | Serialization |
| Affects Version/s: | 2.11.0 |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Gian Maria Ricci | Assignee: | Dmitry Lukyanov (Inactive) |
| Resolution: | Works as Designed | Votes: | 1 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||||||
| Case: | (copied to CRM) | ||||||||
| Description |
|
I have a project that runs perfectly fine with 2.7 drivers. After upgrading to 2.11 we start getting lots of error with the serializer. As an example these are two classes that we use in the project and that worked perfectly with 2.7 driver but fails to be deserialized with 2.11 driver.
Upgrading to 2.11 driver I started got this error.
I do not completely understand why it stopped working and I'm worrying because it worked perfectly with older driver.
Gian Maria.
|
| Comments |
| Comment by Andy Meyvaert [ 03/Aug/23 ] | |||||||||||||||||||||||||||||
|
We are facing exactly the same problem using immutable domain classes. The proposed solution works but is not the way we like to configure our mongo (de)serialisation. The alternative using classmap does not allow null as a default value:
This will throw an error on startup: System.ArgumentNullException: 'Value cannot be null. (Parameter 'defaultValueCreator')' | |||||||||||||||||||||||||||||
| Comment by Gian Maria Ricci [ 11/Jan/21 ] | |||||||||||||||||||||||||||||
|
Sorry for the late response, ok for the solution, I'll try with the attribute. | |||||||||||||||||||||||||||||
| Comment by Dmitry Lukyanov (Inactive) [ 29/Sep/20 ] | |||||||||||||||||||||||||||||
|
Hello alkampfer, thanks for your report, you're right that this behavior was changed in the latest patches. Now, we consider classes that have only private set; as immutable, so this leads to a bit different code path which in turn gives the mentioned error. You're also right about the reason why it fails because the provided document doesn't have all the required fields. The designed path to solve it is to add [BsonDefaultValue(null)] to OtherString field:
| |||||||||||||||||||||||||||||
| Comment by Gian Maria Ricci [ 14/Aug/20 ] | |||||||||||||||||||||||||||||
|
Hi, I've made a repro here https://github.com/alkampfergit/MongoDbDriverExperiments/tree/master/Bugs/CSHARP-3186, the error is the following. We have a base class ABSTRACT, two protected properties. Then we have a derived class, it was born with another private property, and has a constructor with three arguments. We had some objects serialized into database. Then we add another property to derived class, that property is also private and set on constructor. We expect to be able to deserialize old serialized version of the class missing that second property, because we expect serializer to pass null on that parameter. This is true if the property is public, but if the property is private, we have an error in MostArgumentsCreatorSelector.Match because we have four properties in creatorMap.ElementNames (constructor has 4 arguments) but dictionary passed as argument has only three parameters (because it comes from an old version of the object, where the other property is not present). No suitable constructor was match.
Expected behavior: please check if you can pass null to all extra argument on constructor, if you find a suitable constructor is ok, but if you do not find any EXACT constructor, it would be better to find a best match passing null on other arguments. I think that this kind of behavior was introduced with last modification done to ImmutableTypeClassMapConvention class.
| |||||||||||||||||||||||||||||
| Comment by Gian Maria Ricci [ 14/Aug/20 ] | |||||||||||||||||||||||||||||
|
Actually I have an abstract class with some derived classes, that base abstract class is done like this.
Now I have inherited classes like this one
And it does not work. If I made the two property of ReportConfigurationNodeValueObject public instead of protected everything went fine and the driver was able to deserialize everything. I'm still not able to reproduce in a simple test, in that project I also have some custom serializer for some internal id etc, and I wonder where exactly is the problem. If I have a repro I'll happy to attach to this issue. thanks for the attention. |