Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot serialize or deserialize Maps with complex keys #210

Closed
GoogleCodeExporter opened this issue Mar 19, 2015 · 13 comments
Closed

Cannot serialize or deserialize Maps with complex keys #210

GoogleCodeExporter opened this issue Mar 19, 2015 · 13 comments

Comments

@GoogleCodeExporter
Copy link

import java.util.HashMap;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;


public class GsonTest {

    public static void main(String[] args) {

        new GsonTest();

    }

    public GsonTest() {
        HashMap<ComplexKey, String> map = new HashMap<ComplexKey, String>();

        map.put(new ComplexKey("Test1", "Test2"), "Value1");

        Gson gson = new Gson();
        System.out.println(gson.toJson(map, new TypeToken<HashMap<ComplexKey,
String>>(){}.getType()));
    }

    public class ComplexKey {

        private String keyOne;
        private String keyTwo;

        public ComplexKey(String keyOne, String keyTwo) {
            this.keyOne = keyOne;
            this.keyTwo = keyTwo;
        }

        public String getKeyOne() {
            return keyOne;
        }

        public void setKeyOne(String keyOne) {
            this.keyOne = keyOne;
        }

        public String getKeyTwo() {
            return keyTwo;
        }

        public void setKeyTwo(String keyTwo) {
            this.keyTwo = keyTwo;
        }
    }
}

Expected Output:
{"{"keyOne":"Test1","keyTwo":"Test2"}":"Value1"}


Actual Output:
{"GsonTest$ComplexKey@1172e08":"Value1"}


Original issue reported on code.google.com by rev...@paradise.net.nz on 25 May 2010 at 2:53

@GoogleCodeExporter
Copy link
Author

[deleted comment]

@GoogleCodeExporter
Copy link
Author

I have investigated this a bit and written some code (got toJson to work, but 
parsing
fails), but what is really the expected behavior? What you expect is probably 
not
legal JSON, as the quotation marks are nested.

I am beginning to wonder if the best solution for complex keys is to encode it 
as:

{"key":{"keyOne":"Test1","keyTwo":"Test2"},"value":"Value1"}

Original comment by marius.k...@gmail.com on 6 Jun 2010 at 3:56

@GoogleCodeExporter
Copy link
Author

I have implemented the solution mentioned above (with those in an array) in the 
cases the key consists of a complex key (not representable as text).

Patch is attached. The code could maybe be cleaner, but all tests and a new for 
this case passes.

Original comment by marius.k...@gmail.com on 9 Jun 2010 at 12:19

Attachments:

@GoogleCodeExporter
Copy link
Author

Adopting something like the above patch would make my life so much better. :)

Original comment by jsha...@google.com on 28 Aug 2010 at 6:36

@GoogleCodeExporter
Copy link
Author

Issue 224 has been merged into this issue.

Original comment by limpbizkit on 28 Aug 2010 at 8:26

@GoogleCodeExporter
Copy link
Author

Issue 228 has been merged into this issue.

Original comment by limpbizkit on 3 Sep 2010 at 6:50

@GoogleCodeExporter
Copy link
Author

Issue 214 has been merged into this issue.

Original comment by limpbizkit on 3 Sep 2010 at 6:51

@GoogleCodeExporter
Copy link
Author

I did some exploring and it's possible to fix this by registering a type 
adapter. I've created a type adapter that takes any map and serializes it as a 
JSON array. It's pretty fantastic and it should work for anyone stuck on this 
bug.

I'd like to get this patch included in GSON 1.7. I'm not committing it directly 
because we're still stabilizing GSON 1.6.

Original comment by limpbizkit on 8 Nov 2010 at 9:06

  • Changed state: Accepted
  • Added labels: Milestone-Release1.7

Attachments:

@GoogleCodeExporter
Copy link
Author

Well, the only problem with this patch is that you need to explicitly add the 
type adapter. It will not work automatically work and be compatible with data 
saved with older versions, thus it can't be added as default.

My approach above tries to detect if we are dealing with a type that can be 
serialized as string and choose strategy (but i don't remember if it works 
fully, as I don't know too much of the internals of GSon).

Original comment by marius.k...@gmail.com on 9 Nov 2010 at 9:01

@GoogleCodeExporter
Copy link
Author

Fixed in r702 with one explicit type adapter for all maps. This new type 
adapter works for arbitrary maps with both complex and non-complex keys.

Original comment by limpbizkit on 12 Jan 2011 at 12:23

  • Changed state: Fixed

@GoogleCodeExporter
Copy link
Author

For any internet travelers from the future (like myself)... you can enable this 
functionality in GSON 2.* with the enableComplexMapKeySerialization() method on 
GsonBuilder.

Original comment by jakewhar...@gmail.com on 9 Jan 2013 at 8:29

@electronicpeter
Copy link

enableComplexMapKeySerialization() is a great help and should be default. Thanx for the hint!

@inder123
Copy link
Collaborator

@electronicpeter It isn't default because doing so will break backward compatibility

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants