[CSHARP-4112] Auto Mapping of private properties stops working after 2.10 Created: 24/Mar/22  Updated: 22/Jun/22

Status: Backlog
Project: C# Driver
Component/s: None
Affects Version/s: 2.10.1, 2.15.0
Fix Version/s: None

Type: Bug Priority: Unknown
Reporter: Chris McKee Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
related to CSHARP-2995 BsonClassMap.LookupClassMap supports ... Closed

 Description   

Summary

Mapping classes with private setters fails after 2.10
I note this was mentioned a few times but the only ticket I can find relating to this is marked as "gone away"
https://jira.mongodb.org/browse/CSHARP-2995?filter=-5&jql=project%20%3D%20CSHARP%20AND%20text%20~%20%22none%20are%20configured%22%20order%20by%20priority%20DESC%2Cupdated%20DESC

There's also a web post on the same issue
https://www.codewrecks.com/post/general/error-in-mongodb-serializer/

And an ignored forum post on the mongo forum https://www.mongodb.com/community/forums/t/mapping-a-type-with-parameterised-constructor-c-driver-v2-10-2/11856

I'm migrating a project from 2.9x that uses Mongo as part of NEventstore; Switching from 2.9 to 2.10.1/2.15 results in all the mapping of value objects on aggregates (all of which have private setters) failing.
There are no breaking changes mentioned between these versions, yet clearly it breaks, and is not isolated to our usage so I'm trying to work out how best to fix this up.

Please provide the version of the driver. If applicable, please provide the MongoDB server version and topology (standalone, replica set, or sharded cluster).

Tested on 2.10 to present release 2.15



 Comments   
Comment by Chris McKee [ 30/Mar/22 ]

Ahhhh; did the handling change between the 2.9.2 and 10 version then?

Makes sense in the context of the contactinfo entity as someone slapped behaviour into the second constructor.
And of course the other fails because of the string override (strings, strings everywhere)

Thanks for the info as well as looking at a fix. I can at least try and unpick these random things at the same time.

Comment by Dmitry Lukyanov (Inactive) [ 29/Mar/22 ]

Some quick notes:

  1. The issue is related to the fact that for immutable classes we expect that ctor arguments match to class fields by name and type. In your case, one ctor matches, but another one doesn't and, in turn, fails. We should reduce such requirement down to requirement only for one valid ctor.
  2. For now you can use this workaround:

BsonClassMap.RegisterClassMap<GeoCoordinate>(c =>
{
    c.AutoMap();
    c.UnmapConstructor(typeof(GeoCoordinate).GetConstructor(new[] { typeof(string), typeof(string) }));
});
foreach (var aggregateType in TestExtensions.GetTypes())
{
    BsonClassMap.LookupClassMap(aggregateType);
}                        
BsonClassMap.LookupClassMap(typeof(Aggregate));
BsonClassMap.LookupClassMap(typeof(GeoCoordinate));

where you manually exclude unexpected ctor (where ctor argument types don't match to field types)

Comment by Dmitry Lukyanov (Inactive) [ 29/Mar/22 ]

chris.mckee@ivendi.com, thanks, we've found out the root cause of your issue and will consider fixing it in next releases.

Comment by Dmitry Lukyanov (Inactive) [ 29/Mar/22 ]

The issue can be simplified to this small repro:

        public class ClassWith2Constructors
        {
            public ClassWith2Constructors(double x) // mapped ctor
            {
                X = x;
            }            
            public ClassWith2Constructors(int x) // will fail since ctor argument type doesn't match with field type
            {
                X = x;
            }            
            public double X { get; }
        }

 

Use it like:

new ClassWith2Constructors(1).ToJson();

the issue will be triggered here.

Exception:

'Creator map for class MongoDB.Bson.Tests.Jira.CSharp1559Tests+ClassWith2Constructors has 1 arguments, but none are configured.'

I think we should not require matching property types/names in all ctors presented in the class. It should be enough to have only one valid ctor.

Comment by Chris McKee [ 28/Mar/22 ]

Hope the gists are ok; seemed easier to change than upload files 😜

Comment by Chris McKee [ 25/Mar/22 ]

And yep switching the immutable class back fixed the issue
https://gist.github.com/ChrisMcKee/b541baf9f5191a3f01eb8f96d0e03030

I'm assuming theres a change to setup that's necessary to avoid this hack

Comment by Chris McKee [ 24/Mar/22 ]

I've added a failure at mapping level here https://gist.github.com/ChrisMcKee/e6c22d0e94e3c60bb5a15959f7d7d74c

There's more errors in the first gist but this at least shows the failure in mapping linked types (aggregate > entity) from 2.10 onward.

Hope thats helpful

Comment by Chris McKee [ 24/Mar/22 ]

Sounds like the right area

Its mostly throwing on the value types in an aggregate class. The mappings failing at the point where it tries to deal with the entity

I've popped the value type / entity in a gist with the errors being thrown https://gist.github.com/ChrisMcKee/42a2a51f61031420d1b6d5df165e998c
We don't map it directly; its used as a property in the aggregate so we were automapping all the classes using the aggregate base (reflection over aggregates using base type / calling BsonClassMap.LookupClassMap with type.

Comment by Dmitry Lukyanov (Inactive) [ 24/Mar/22 ]

Hey chris.mckee@ivendi.com , thanks for your report,

This behavior has been slightly changed in CSHARP-2889. Please see this comment https://jira.mongodb.org/browse/CSHARP-2889?focusedCommentId=3212482&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-3212482 for details. To proceed here can you please provide class structure that you use?

Generated at Wed Feb 07 21:47:15 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.