google-code-export / morphia

Automatically exported from code.google.com/p/morphia
1 stars 0 forks source link

Support the persistence of maps with non-string keys #298

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
When you attempt to create an entity with a map that isn't keyed by something 
that isn't considered "primitive-like" by 
com.google.code.morphia.utils.ReflectionUtils.isPrimitiveLike, the exception 
below is raised.  It would be nice if there was a built-in way to map these, 
since it's not uncommon to key a map by something more complex.  The existing 
map handlers could be easily extended to persist these as an array of objects 
with a "key" and a "value" property, like this:

[
{
    "key":
    {
        "className": "blah",
        "property1": "c9e1d7db-af16-4d7c-91fc-204e97cf0df0",
        "property2": "c9e1d7db-af16-4d7c-91fc-204e97cf0df0"
    },
    "value":
    {
        "className": "blah",
        "property1": "abc",
        "property2": "def"
    }
},
{
    "key":
    {
        "className": "blah",
        "property1": "f9d1d7db-af16-4d7c-91fc-204e97cf0df0",
        "property2": "f9d1d7db-af16-4d7c-91fc-204e97cf0df0"
    },
    "value":
    {
        "className": "blah",
        "property1": "jkl",
        "property2": "mno"
    }
}]

I've done this in an entity interceptor, using special annotations on the 
fields I want, but this approach has drawbacks, including that the fields can't 
be queried without turning off validation, and that it doesn't work for nested 
values (a collection of maps for instance).

What version are you using? (Morphia/Driver/MongoDB)

0.99/2.53/1.8.1

Please include a stack trace below:
com.google.code.morphia.mapping.validation.ConstraintViolationException: Number 
of violations: 1
MapKeyDifferentFromString complained about blah.blah : Maps must be keyed by a 
simple type (Map<String/Enum/Long/ObjectId/..., ?>); class blah.blah is not 
supported as a map key type.
    at com.google.code.morphia.mapping.validation.MappingValidator.validate(MappingValidator.java:66)
    at com.google.code.morphia.mapping.validation.MappingValidator.validate(MappingValidator.java:155)
    at com.google.code.morphia.mapping.MappedClass.validate(MappedClass.java:259)
    at com.google.code.morphia.mapping.Mapper.addMappedClass(Mapper.java:154)
    at com.google.code.morphia.mapping.Mapper.addMappedClass(Mapper.java:142)
    at com.google.code.morphia.Morphia.map(Morphia.java:55)
    at com.cengage.mongo.MongoWrapper.initialize(MongoWrapper.java:131)
    ... 26 more

Original issue reported on code.google.com by ross.lo...@gmail.com on 7 Jul 2011 at 4:53

GoogleCodeExporter commented 9 years ago
This is getting a little complex and might be better reflected in your class by 
storing a class to abstract this. I don't see this as a generally good feature 
but I'm happy to be convinced otherwise. 

I'd suggest starting a discussion on the list or getting votes together.

Original comment by scotthernandez on 5 Aug 2011 at 10:24

GoogleCodeExporter commented 9 years ago
+1 Looking forward to implement a lazy loaded Map where the key is actually an 
Entity. 

Original comment by ma...@mashape.com on 17 Oct 2011 at 1:56

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
I agree this would be very helpful. Without it, I have to change quite a lot 
about my application in order to use Morphia (but otherwise Morphia has been 
great).

Original comment by ankursha...@gmail.com on 3 Jan 2012 at 4:28

GoogleCodeExporter commented 9 years ago
Most likely the implementations for this would be storing the map entries in an 
array rather than as fields with the key values.

Original comment by scotthernandez on 3 Jan 2012 at 4:48