<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Thu Feb 08 08:58:31 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>MongoDB Jira</title>
    <link>https://jira.mongodb.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>9.7.1</version>
        <build-number>970001</build-number>
        <build-date>13-04-2023</build-date>
    </build-info>


<item>
            <title>[JAVA-2981] Manage Enum type as Map keys</title>
                <link>https://jira.mongodb.org/browse/JAVA-2981</link>
                <project id="10006" key="JAVA">Java Driver</project>
                    <description>&lt;p&gt;Hello,&lt;/p&gt;

&lt;p&gt;Current limitation of the MapCodec is that it only manages Map&amp;lt;K,V&amp;gt; with K being necessarily String.&lt;/p&gt;

&lt;p&gt;It could be quite easy and useful to extend this to Enums in a first step, and to any type that can be serialized/deserialized to/from String.&lt;/p&gt;

&lt;p&gt;An idea to be able to manage any type as a map&apos;s key is to introduce a kind of &quot;key codec&quot; interface that defines how should a certain type be encoded/decoded if it appears as a map&apos;s key. It could even be a converter rather than a general codec since we know that the target type is necessarily String.&lt;/p&gt;

&lt;p&gt;&#160;&lt;/p&gt;

&lt;p&gt;Cheers&lt;/p&gt;

&lt;p&gt;Farid&lt;/p&gt;</description>
                <environment></environment>
        <key id="606412">JAVA-2981</key>
            <summary>Manage Enum type as Map keys</summary>
                <type id="4" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14710&amp;avatarType=issuetype">Improvement</type>
                                            <priority id="3" iconUrl="https://jira.mongodb.org/images/icons/priorities/major.svg">Major - P3</priority>
                        <status id="6" iconUrl="https://jira.mongodb.org/images/icons/statuses/closed.png" description="The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.">Closed</status>
                    <statusCategory id="3" key="done" colorName="success"/>
                                    <resolution id="2">Won&apos;t Fix</resolution>
                                        <assignee username="ross@mongodb.com">Ross Lawley</assignee>
                                    <reporter username="fbg">Farid BG</reporter>
                        <labels>
                    </labels>
                <created>Tue, 18 Sep 2018 09:51:48 +0000</created>
                <updated>Tue, 11 Dec 2018 09:37:55 +0000</updated>
                            <resolved>Tue, 11 Dec 2018 09:37:06 +0000</resolved>
                                    <version>3.0.0</version>
                                                    <component>BSON</component>
                    <component>POJO</component>
                                        <votes>0</votes>
                                    <watches>2</watches>
                                                                                                                <comments>
                            <comment id="2086690" author="ross@10gen.com" created="Tue, 11 Dec 2018 09:37:06 +0000"  >&lt;p&gt;Hi &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=fbg&quot; class=&quot;user-hover&quot; rel=&quot;fbg&quot;&gt;fbg&lt;/a&gt;,&lt;/p&gt;

&lt;p&gt;I&apos;m glad you were able to use the &lt;tt&gt;PropertyCodecProvider&lt;/tt&gt; to meet your requirements. This is a good example of why the abstraction was introduced and how it can be used.  I can see why a custom Key Converter might help reduce the boiler plate with your abstraction, alternative approaches could be custom Map implementations that allow Codecs / PropertyCodecProviders to handle the conversion of types. &lt;/p&gt;

&lt;p&gt;There are no current plans to allow alternative types as keys for Maps by default - for that reason I&apos;m closing this ticket as Won&apos;t Fix. However, I will happily review should there be more demand for such a feature. So please comment if you feel this is a missing feature in the PojoCodec.&lt;/p&gt;

&lt;p&gt;Ross&lt;/p&gt;</comment>
                            <comment id="2085557" author="fbg" created="Mon, 10 Dec 2018 15:48:24 +0000"  >&lt;p&gt;Hi Ross,&lt;/p&gt;

&lt;p&gt;Thank you for you response.&lt;/p&gt;

&lt;p&gt;I had a look at the examples you provided. My problem with creating a custom Codec for each Map with a different key type is that there would be a lot a code duplication. Basically, the whole logic is the same except for the way the key is encoded/decoded to/from a string.&lt;/p&gt;

&lt;p&gt;The reason I think that Enum types should be managed out of the box is that their string representation is quite obvious; whether it should be the name() or toString() or ordinal() is a matter of convention. I personally think the name() would be the most adequate choice, as the method is final, and the output string of that method enables to find the right instance of the enum. Although the ordinal() method bears the same properties as the aforementionned, it does not visually convey the same information as the name of the enum. Developers will usually name their Enums in a meaningful way that is understandable directly, even outside the scope of the application, i.e. someone reading a document directly in the db would better understand it if he sees meaningful strings as keys rather than numbers. Performance wise, I don&apos;t think it makes any difference if its the name() or ordinal() since they are all stored as strings in the db. I ruled out the toString() earlier on since it can be overridden by the developer, and the mecanism for decoding the enum would be more painful, although not impossible.&lt;/p&gt;

&lt;p&gt;I did manage to create my own custom MapPropertyCodecProvider. I wrote it in a way that manages Strings and Enums out of the box. It can also manage any other type, given that you provide a KeyConverter for each key type you want to manage, which is an interface I defined with methods to convert to and from a String. The problem with this approach is that the KeyConverters I provide to my custom MapPropertyCodecProvider before registering it to the Pojo Codec are not reachable outside the scope of my MapPropertyCodecProvider. Say I need to create another custom PropertyCodecProvider that needs to deals with Pojos as keys (like a multimap for example), well i&apos;ll have to manually register the (possibly) same KeyConverters to that PropertyCodecProvider as well. To summarize, there is no centralized repository of KeyConverters. But hey, nothing is perfect!&lt;/p&gt;

&lt;p&gt;As I said in the issue&apos;s description, I don&apos;t expect such a mechanism to be implemented on the short-term, as it involves some considerable design choices to be made, in addition to determining whether this is really a feature required by users; plus there is a way to manage it manually with the current driver. But the management of Enums would be quite useful and easy to incorporate into the current MapCodecProvider, so I am quite eager to see this feature implemented.&lt;/p&gt;

&lt;p&gt;Thank you again for your help.&lt;/p&gt;

&lt;p&gt;Farid&lt;/p&gt;</comment>
                            <comment id="2085423" author="ross@10gen.com" created="Mon, 10 Dec 2018 14:37:55 +0000"  >&lt;p&gt;Hi &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=fbg&quot; class=&quot;user-hover&quot; rel=&quot;fbg&quot;&gt;fbg&lt;/a&gt;,&lt;/p&gt;

&lt;p&gt;Thanks for the ticket, encoding Map&apos;s with an Enum Key could be explicitly controlled by custom codecs for use within &lt;tt&gt;Document&lt;/tt&gt; classes, however, the lack of type information when decoding into a &lt;tt&gt;Document&lt;/tt&gt; wouldn&apos;t make it feasible for the general case.&lt;/p&gt;

&lt;p&gt;I believe the current &lt;tt&gt;Codec&lt;/tt&gt; infrastructure is flexible enough to handle this process for Pojo Codecs. As Pojo classes can provide their own &lt;tt&gt;PropertyCodecProvider&lt;/tt&gt; to handle encoding nested / complex types.  One such example in tests uses an &lt;tt&gt;Integer&lt;/tt&gt; for a map key. The &lt;a href=&quot;https://github.com/mongodb/mongo-java-driver/blob/r3.9.1/bson/src/test/unit/org/bson/codecs/pojo/entities/InvalidMapModel.java&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;InvalidMapModel&lt;/a&gt; isn&apos;t valid out the box but a test can be seen in the &lt;a href=&quot;https://github.com/mongodb/mongo-java-driver/blob/r3.9.1/bson/src/test/unit/org/bson/codecs/pojo/PojoCustomTest.java#L432-L436&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;PojoCustomTest&lt;/a&gt; that shows by providing a &lt;a href=&quot;https://github.com/mongodb/mongo-java-driver/blob/r3.9.1/bson/src/test/unit/org/bson/codecs/pojo/entities/InvalidMapPropertyCodecProvider.java&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;InvalidMapPropertyCodecProvider&lt;/a&gt; the map key can be roundtripped.&lt;/p&gt;

&lt;p&gt;Should &lt;tt&gt;Map&amp;lt;Enum, T&amp;gt;&lt;/tt&gt; be supported out the box? This I&apos;m slightly less convinced about because there are multiple ways to store the value of an &lt;tt&gt;Enum&lt;/tt&gt; - theres the &lt;tt&gt;toString&lt;/tt&gt; value, the &lt;tt&gt;name&lt;/tt&gt; value or even the ordinal position. Finally, there is a chance of receiving data that doesn&apos;t match an &lt;tt&gt;Enum&lt;/tt&gt; value at all.  A simple &lt;tt&gt;Map&amp;lt;String, Object&amp;gt;&lt;/tt&gt; doesn&apos;t have these limitations.&lt;/p&gt;

&lt;p&gt;Have you considered providing a custom Codec for &lt;tt&gt;Map&amp;lt;Enum, T&amp;gt;&lt;/tt&gt; or using a custom &lt;tt&gt;PropertyCodecProvider&lt;/tt&gt;?&lt;/p&gt;

&lt;p&gt;Ross&lt;/p&gt;</comment>
                    </comments>
                    <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_15850" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_12550" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2|hu3qv3:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10558" key="com.pyxis.greenhopper.jira:gh-global-rank">
                        <customfieldname>Rank (Obsolete)</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>9223372036854775807</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            </customfields>
    </item>
</channel>
</rss>