[JAVA-4636] Codec Support for any type of Map key Created: 31/May/22  Updated: 22/Jun/22

Status: Backlog
Project: Java Driver
Component/s: POJO
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Unknown
Reporter: Greg Stewart Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Currently, it seems that the default set of Codecs supports just `Map<String, Object>`. This is fine for many use cases, but there is often the use case to use any number of key types.

Currently, I have a (most likely/ obviously) sub-optimal solution that looks like this: https://stackoverflow.com/questions/67849754/mongodb-mapk-v-codec-maps-must-have-string-keys-fix (not my code)

This works most of the time, but seems to hate `Map<ObjectId, *>` types.

 

There should be a standardized codec that can handle any type of map.

 



 Comments   
Comment by Ross Lawley [ 20/Jun/22 ]

Hi contact@gjstewart.net,

Thanks for the ticket. I'm glad you have a work around. Its an interesting problem as Bson requires keys to be Strings, so the issue is how to convert to strings in a meaningful way. Also, round tripping may be a requirement as well, and keeping the same types.

I think a custom codec is possibly the best solution for now. We do have an annotation @BsonRepresentation that was added to handle single types but it wouldn't be ideal for handling maps.

I'm going to put this ticket on the backlog for future consideration. If you have any extra feedback or usecases then please add to the ticket and that may help with the scheduling.

Many thanks,

Ross

Comment by Greg Stewart [ 11/Jun/22 ]

After some adjustment and debugging, I have a solution that should be adequate, but I haven't added all the class cases I have listed above. I am sure there is more to tweak for an 'official' version, but here's what I got:

Codec:
https://github.com/Epic-Breakfast-Productions/OpenQuarterMaster/blob/a68718304e1cfa6a9b51d59dc9eefe339794f2a0/software/open-qm-base-station/src/main/java/com/ebp/openQuarterMaster/baseStation/mongoUtils/codecs/AnyMapCodec.java
Codec Provider:
https://github.com/Epic-Breakfast-Productions/OpenQuarterMaster/blob/a68718304e1cfa6a9b51d59dc9eefe339794f2a0/software/open-qm-base-station/src/main/java/com/ebp/openQuarterMaster/baseStation/mongoUtils/AnyMapCodecProvider.java

Comment by Greg Stewart [ 01/Jun/22 ]

I'll add that the scope of "any" object should probably be limited to:

  • all primitive-based (char, int, etc)
  • a selection of Java-util based objects
    • Date/ timestamps (new and old)
    • Url's/ URI's
    • Other, similar with simple to/from string methods
  • Any Enum values
  • Bson's ObjectId

Bonus points for being able to handle any class that we have a codec for already. Alternatively, could have a method for adding your own to/fromString methods for specific clases; something like `register(Class<T> clazz, Supplier<T> toStringMethod, Consumer<T> fromStringMethod)` (I think I am getting my java8 correct there)

I would expect that the generated bson would be such that the keys in the map were searchable, with non-bson-equivalent values be turned to generic strings for the keys, rather than using a wrapping object to store the key alongside the data.

Generated at Thu Feb 08 09:02:35 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.