spring-data-mongodb icon indicating copy to clipboard operation
spring-data-mongodb copied to clipboard

$all BadValue Exception if Collection with one element is passed

Open YuriiAndreitsev opened this issue 1 year ago • 2 comments

if one element in Collection is passed in .all() criteria it is not preserved as array in spring-data-mongodb higher that 4.3.0

image

image

YuriiAndreitsev avatar Jul 03 '24 11:07 YuriiAndreitsev

Thank you for getting in touch. Please do not upload images but take the time to provide a complete minimal sample (something that we can unzip or git clone, build, and deploy) that reproduces the problem. Thank you!

christophstrobl avatar Jul 03 '24 11:07 christophstrobl

okay, sorry for that, i will take a note of that,

i've debugged a little bit, it look like in this method it skips in the first phase it skips if ("$nin".equals(key) || "$in".equals(key)) and in result recursively converts objectId from array with single element into one objectId and of course it becomes invalid for $all operator

`

      private Object convertIdField(Field documentField, Object source) {

	Object value = source;
	if (isDBObject(source)) {
		DBObject valueDbo = (DBObject) source;
		value = new Document(valueDbo.toMap());
	}

	if (!isDocument(value)) {
		return convertId(value, getIdTypeForField(documentField));
	}

	Document valueDbo = (Document) value;
	Document resultDbo = new Document(valueDbo);

	for (Entry<String, Object> entry : valueDbo.entrySet()) {

		String key = entry.getKey();
		if ("$nin".equals(key) || "$in".equals(key)) {
			List<Object> ids = new ArrayList<>();
			for (Object id : (Iterable<?>) valueDbo.get(key)) {
				ids.add(convertId(id, getIdTypeForField(documentField)));
			}
			resultDbo.put(key, ids);
		} else if (isKeyword(key)) {
			resultDbo.put(key, convertIdField(documentField, entry.getValue()));
		} else {
			if (documentField.getProperty() != null && documentField.getProperty().isEntity()) {
				Field propertyField = createPropertyField(documentField.getPropertyEntity(), key, mappingContext);
				resultDbo.put(key, getMappedValue(propertyField, entry.getValue()));
			} else {
				resultDbo.put(key, getMappedValue(documentField, entry.getValue()));
			}
		}
	}

	return resultDbo;
}`

YuriiAndreitsev avatar Jul 03 '24 12:07 YuriiAndreitsev

Thank you @YuriiAndreitsev - I was able to reproduce the issue. We'll have a closer look!

christophstrobl avatar Jul 05 '24 13:07 christophstrobl