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

Different Queries, same hashCodes #4032

Closed
kusamau opened this issue Apr 21, 2022 · 7 comments · May be fixed by #4831
Closed

Different Queries, same hashCodes #4032

kusamau opened this issue Apr 21, 2022 · 7 comments · May be fixed by #4831
Assignees

Comments

@kusamau
Copy link

kusamau commented Apr 21, 2022

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

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Apr 21, 2022
@mp911de mp911de added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels Nov 7, 2022
@13wjdgk
Copy link

13wjdgk commented Nov 10, 2024

PR : #4831

@mp911de
Copy link
Member

mp911de commented 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).

@mp911de mp911de added status: waiting-for-triage An issue we've not yet triaged status: waiting-for-feedback We need additional information before we can continue and removed type: bug A general bug labels Nov 11, 2024
@13wjdgk
Copy link

13wjdgk commented 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!

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Nov 12, 2024
@injae-kim
Copy link

Taking a step back, what problem are you trying to solve?

Yes hashCode is not required to be unequal for not equal objects.

But specially on Query, cause it uses hashMap.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 overload hashCode() to not easily generate same hashCode of Query?

@mp911de
Copy link
Member

mp911de commented Nov 12, 2024

But specially on Query, cause it uses hashMap.put(key, 0 or 1) on .include() and .exclude(), same hashCode can be generated too easily on different query.

Are you running into a performance issue or a bug? What problem are you trying to solve? Same hashCodes are only a symptom.

@mp911de mp911de added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Nov 12, 2024
@injae-kim
Copy link

oh actually there's no big problem, but I found that hashCode can be same too easily on Query :)

If you think this is not bug and only a symptom, we can just close issue ~!

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Nov 14, 2024
@mp911de mp911de closed this as not planned Won't fix, can't repro, duplicate, stale Nov 14, 2024
@mp911de mp911de removed status: waiting-for-triage An issue we've not yet triaged status: feedback-provided Feedback has been provided labels Nov 14, 2024
@mp911de
Copy link
Member

mp911de commented Nov 14, 2024

Closing as we do not indent to update our hashCode calculation at the moment. We might come back to this ticket once we find cases where same hashCodes cause inconvenience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants