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

Embedded entity with mixup of strings and long for the same attribute works till 2.2.X but not upon 2.3.X #2200

Closed
MichaBub opened this issue Jan 10, 2023 · 4 comments
Labels
Milestone

Comments

@MichaBub
Copy link

MichaBub commented Jan 10, 2023

Describe the bug
Having an embedded entity annotated as entity can be properly mapped / read from DB with 2.2, but not with 2.3
Attention: The documents in mongo for this error can be either contain string or long values - this worked fine with 2.2, not with 2.3

e.g. Java class:

@Entity(useDiscriminator = false)
public class MyId implements Serializable {
    private static final long serialVersionUID = -1L;
    protected long myId;
    public MyId() {
    }
    public MyId(long myId) {
        this.myId = myId;
    }
    public MyId(String myId) {
        this.myId = Long.parseLong(myId);
    }
}

and data in mongo with mixup of long and string

{
    "_id" : {
        "identifier" : "1"
    },
	"blabla" : {
        "myId" : NumberLong(123)
    }
},
{
    "_id" : {
        "identifier" : "2"
    },
	"blabla" : {
        "myId" : "1234"
    }
}

will result in:
Caused by: dev.morphia.mapping.MappingException: The type 'xxx.xxx.MyId' can not be instantiated: Can not set long field xxx.xxx.myId to java.lang.String

@MichaBub MichaBub added the bug label Jan 10, 2023
@evanchooly
Copy link
Member

Can you put together a reproducer? I'm not sure how that would work under 2.2 but not 2.3, either.

@MichaBub
Copy link
Author

MichaBub commented Jan 12, 2023

Hi @evanchooly

I invested time in fixing this issue not writing the sample code with reproducer yet.
--> Loading all documents from mongo with 2.2, and deleting plus saving again every single document did the trick.

But I can tell you it works with 2.2 and the mixup of string/long/int fields in mongo with this trick (this API got removed in 2.3):

datastore.getMapper().mapExternal(null, aggregate);

see full implementation:

        MapperOptions mapperOptions = MapperOptions.builder()
                .collectionNaming(NamingStrategy.identity())
                .propertyNaming(NamingStrategy.identity())
                .build();
        datastore = Morphia.createDatastore(mongoClient, this.dbName, mapperOptions);

        Set<Class<?>> aggregates = loadAnnotatedWithEntity();
        for (Class aggregate : aggregates) {
            datastore.getMapper().map(aggregate);
            datastore.getMapper().mapExternal(null, aggregate);
            datastore.ensureIndexes(aggregate);
        }
    }

    public static Set<Class<?>> loadAnnotatedWithEntity() {
        Reflections reflections = new Reflections("com.mypackage");
        Set<Class<?>> classes = reflections.getTypesAnnotatedWith(Entity.class);
        return classes;
    }

How can you get the attribute which is type long in the entity as type string in the mongo database.
--> Via a plain json importer which loads anything as document in your db:
But anyway, the issue is about reading the entity, which works with 2.2 but not with 2.3

        MongoCollection<BasicDBObject> collection = datastore
                .getDatabase()
                .getCollection("myCollection", BasicDBObject.class);
        BasicDBObject document = BasicDBObject.parse(StreamUtilUTF8.fromInputStream(this.getClass().getClassLoader().getResourceAsStream("json/myfile.json")));
        collection.insertOne(document);

@MichaBub MichaBub changed the title Having an embedded entity mapping works with 2.2, not with 2.3 Having an embedded entity with mixup of strings and long for the same attribute in mongo works with 2.2 but not with 2.3 anymore Jan 12, 2023
@evanchooly
Copy link
Member

that reproducer would really help. Seeing what changes in the database would be useful to see.

@MichaBub
Copy link
Author

Hi @evanchooly

okay I wrote reproducer tests to compare

Morphia 2.2.3 - working
https://github.com/MichaBub/reproducer/tree/works_with_morphia_2_2_3

Morphia 2.3.0 - broken
https://github.com/MichaBub/reproducer/tree/broken_with_morphia_2_3

and the diff of changes:
https://github.com/MichaBub/reproducer/pull/5/files

you´ll get the error as described with 2.3 - with 2.2.3 all works fine.

dev.morphia.mapping.MappingException: The type 'com.foo.MyId' can not be instantiated: Can not set long field com.foo.MyId.myId to java.lang.String

	at dev.morphia.mapping.internal.ConstructorCreator.getInstance(ConstructorCreator.java:118)
	at dev.morphia.mapping.codec.pojo.EntityDecoder.decode(EntityDecoder.java:43)

@MichaBub MichaBub changed the title Having an embedded entity with mixup of strings and long for the same attribute in mongo works with 2.2 but not with 2.3 anymore Embedded entity with mixup of strings and long for the same attribute works till 2.2.X but upon 2.3.X Jan 13, 2023
@MichaBub MichaBub changed the title Embedded entity with mixup of strings and long for the same attribute works till 2.2.X but upon 2.3.X Embedded entity with mixup of strings and long for the same attribute works till 2.2.X but noz upon 2.3.X Jan 13, 2023
@MichaBub MichaBub changed the title Embedded entity with mixup of strings and long for the same attribute works till 2.2.X but noz upon 2.3.X Embedded entity with mixup of strings and long for the same attribute works till 2.2.X but not upon 2.3.X Jan 13, 2023
@evanchooly evanchooly added this to the 2.3.1 milestone Jan 22, 2023
evanchooly added a commit that referenced this issue Jan 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants