Skip to content

Inconsistent type alias placement in list of classes [DATAMONGO-1509] #2420

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

Closed
spring-projects-issues opened this issue Oct 12, 2016 · 4 comments
Assignees
Labels
in: mapping Mapping and conversion infrastructure type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link

Tomasz Grabarczyk opened DATAMONGO-1509 and commented

I have the following classes:

@Document
public class TestDocument {
	
	@Id private String id;
	private List<TestClass> testClassList;

	public TestDocument() {
		this.testClassList = null;
	}
	
	public TestDocument(List<TestClass> testClassList) {
		this.testClassList = testClassList;
	}
}
public class TestClass { }
public class TestSubClass extends TestClass {

	private String field;

	public TestSubClass(String field) {
		this.field = field;
	}
}

Now I run the following code:

TestClass testClass = new TestSubClass("value");
mongoTemplate.insert(new TestDocument(Arrays.asList(testClass)));
Query query = Query.query(Criteria.where("testClassList").is(testClass));
TestDocument result = mongoTemplate.findOne(query, TestDocument.class);
System.out.println(result);		// prints: null

I would expect that this query should return the document I inserted at the beginning, but it doesn't. The reason for that is that the TestClass is converted differently when saving document, and differently when creating the query:

Document saved to the database:

"_id" : ObjectId("57fe47fd24474e28ec1db2ed"),
"_class" : "TestDocument",
"testClassList" : [
    {
        "field" : "value",
        "_class" : "TestSubClass"
    }
]

The query:

{ "testClassList" : { "_class" : "TestSubClass" , "field" : "value"}}

I think it shouldn't be like that


Affects: 1.10 M1 (Ingalls), 1.9.4 (Hopper SR4)

Issue Links:

  • DATAMONGO-1210 Inconsistent property order of _class type hint breaks document equality

Referenced from: pull request #411, and commits e987a85, 987461a, c9573ed, 3c16b4d, 8c50baa, 0ee8789, d6f560d

@spring-projects-issues
Copy link
Author

Tomasz Grabarczyk commented

I was able to successfully circumvent this issue by changing DefaultMongoTypeMapper.DBObjectTypeAliasAccessor#writeTypeTo to:

@Override
public void writeTypeTo(DBObject sink, Object alias) {
	if (typeKey == null) return;
	if (sink instanceof BasicDBObject) {
		prependObject((BasicDBObject) sink, typeKey, alias);
	} else {
		sink.put(typeKey, alias);
	}
}


// Puts the given entry (key and object) at the beginning of the given BasicDBObject
private void prependObject(BasicDBObject dbObject, String key, Object object) {
	BasicDBObject objectCopy = new BasicDBObject();
	objectCopy.append(key, object);
	objectCopy.putAll(dbObject.toMap());
	dbObject.clear();
	dbObject.putAll(objectCopy.toMap());
}

but it is probably not the best solution

@spring-projects-issues
Copy link
Author

Oliver Drotbohm commented

Maybe I am missing something here but are you saying the query doesn't match if _class appears before field in the query and it's stored the other way around in the document?

@spring-projects-issues
Copy link
Author

Tomasz Grabarczyk commented

Yes, the query doesn't match in that case. This behavior is documented in MongoDb docs, which says:

Equality matches on an embedded document require an exact match of the specified <value>, including the field order

@spring-projects-issues
Copy link
Author

Christoph Strobl commented

thanks for reporting - yes the order of _class seems to get messed up during the conversion. Will need to have a closer look where that actually happens

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: mapping Mapping and conversion infrastructure type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants