Not planned
Description
Consider two org.springframework.data.mongodb.core.query.Query instances almost identical except for one projection field which is
- included in one query
- excluded in the other query
then the following test fails
Assertions.assertNotEquals(queryWithExclude.hashCode(), queryWithInclude.hashCode());
Unit Test
@Test
public void hashMapQueryTest() {
Query queryWithExclude = new Query();
queryWithExclude.fields().exclude("key1");
queryWithExclude.fields().exclude("key2");
Query queryWithInclude = new Query();
queryWithInclude.fields().include("key1");
queryWithInclude.fields().include("key2");
Assertions.assertNotEquals(queryWithExclude.hashCode(), queryWithInclude.hashCode());
}
Comments
The problem can be drilled down to the Field.hashCode()
ObjectUtils.nullSafeHashCode(this.criteria);
which seems to fails due to the HashMap implementation itself as proved by the following test
@Test
public void hashMapZeroOneTest() {
HashMap<String, Integer> fieldZero = new HashMap<>();
fieldZero.put("key1", 0);
fieldZero.put("key2", 0);
HashMap<String, Integer> fieldOne = new HashMap<>();
fieldOne.put("key1", 1);
fieldOne.put("key2", 1);
Assertions.assertNotEquals(fieldZero.hashCode(), fieldOne.hashCode());
}
however tests with other numbers than 0 or 1 works.
To conclude, the problem seem related to the use of 0 and 1 in the Field.criteria which then are translated according to the mongo projection syntax. Possible solution could be to replace in the Field class 0/1 used by include/exclude with enum INCLUDE/EXCLUDE values and consequently modify up to various get[Query|Field]Object().
Comments?
Regards,
Maurizio
Metadata
Metadata
Assignees
Labels
No labels
Activity
13wjdgk commentedon Nov 10, 2024
PR : #4831
mp911de commentedon Nov 11, 2024
hashCode
is not required to be unequal for two objects that do not equal each other.Taking a step back, what problem are you trying to solve? Looking at the attached pull request, performance gets worse by an order of magnitude by introducing allocations (
toString
rendering).13wjdgk commentedon Nov 12, 2024
@mp911de
According to the official Java documentation, equal objects must have the same hash code. However, in the current query example, non-equal objects are returning the same hash code.
If the
toString()
method is inefficient, could you review the alternative method I suggested in the PR comments?Thank you for your comment!
injae-kim commentedon Nov 12, 2024
Yes
hashCode
is not required to be unequal for not equal objects.But specially on
Query
, cause it useshashMap.put(key, 0 or 1)
on.include() and .exclude()
, same hashCode can be generated too easily on different query.So how about using
hashMap.toString()
or overloadhashCode()
to not easily generate same hashCode of Query?mp911de commentedon Nov 12, 2024
Are you running into a performance issue or a bug? What problem are you trying to solve? Same hashCodes are only a symptom.
9 remaining items