Skip to content

Problem with the hashCode method of Criteria when it contains subcriteria #3083

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
domenicofasano99 opened this issue Mar 27, 2025 · 1 comment · Fixed by #3088
Closed

Problem with the hashCode method of Criteria when it contains subcriteria #3083

domenicofasano99 opened this issue Mar 27, 2025 · 1 comment · Fixed by #3088
Labels
type: bug A general bug

Comments

@domenicofasano99
Copy link

domenicofasano99 commented Mar 27, 2025

I have developed a system that iteratively creates Criteria based on an account's configurations, and the resulting output generated by the system looks something like this:

        Criteria criteria = new Criteria("first").is("hello");
        List<Criteria> criterias = new ArrayList<>();
        criterias.add(new Criteria().or("second").exists());
        List<Criteria> subCriterias = new ArrayList<>();
        subCriterias.add(new Criteria("third").exists()
                .and(new Criteria("fourth").is("ciao")));
        subCriterias.add(new Criteria("third").exists()
                .and(new Criteria("fourth").is("hi")));
        Criteria result = Criteria.or();
        for (Criteria c : criterias) {
            result = result.or(c);
        }
        for (Criteria c : subCriterias) {
            result = result.subCriteria(c);
        }
        criteria = criteria.subCriteria(result);

The issue is that in the subCriteria, I sometimes have to repeat "third-exists" in different subCriteria because one of them might not exist. This means I cannot optimize it into something like (third exists AND (fourth is "ciao" OR fourth is "hi")).

The main problem is that the hashCode() function only considers the first level, sees that both subCriteria start with "third-exists", and therefore decides not to add the second one to the subCriteria.

I am also attaching a test case in the CriteriaQueryMappingUnitTests class that reproduces this scenario.

      void subCriteriaTest() throws JSONException {
        Criteria criteria = new Criteria("first").is("hello");

        List<Criteria> criterias = new ArrayList<>();
        criterias.add(new Criteria().or("second").exists());
        List<Criteria> subCriterias = new ArrayList<>();
        subCriterias.add(new Criteria("third").exists()
                .and(new Criteria("fourth").is("ciao")));
        subCriterias.add(new Criteria("third").exists()
                .and(new Criteria("fourth").is("hi")));
        Criteria result = Criteria.or();
        for (Criteria c : criterias) {
            result = result.or(c);
        }
        for (Criteria c : subCriterias) {
            result = result.subCriteria(c);
        }
        criteria = criteria.subCriteria(result);
        CriteriaQuery criteriaQuery = new CriteriaQuery(criteria);


        String expected = """
                {
			 "bool": {
				 "must": [
					 {
						 "query_string": {
							 "default_operator": "and",
							 "fields": [
								 "first"
							 ],
							 "query": "hello"
						 }
					 },
					 {
						 "bool": {
							 "should": [
								 {
									 "exists": {
										 "field": "second"
									 }
								 },
								 {
									 "bool": {
										 "must": [
											 {
												 "exists": {
													 "field": "third"
												 }
											 },
											 {
												 "query_string": {
													 "default_operator": "and",
													 "fields": [
														 "fourth"
													 ],
													 "query": "ciao"
												 }
											 }
										 ]
									 }
								 },
								 {
									 "bool": {
										 "must": [
											 {
												 "exists": {
													 "field": "third"
												 }
											 },
											 {
												 "query_string": {
													 "default_operator": "and",
													 "fields": [
														 "fourth"
													 ],
													 "query": "hi"
												 }
											 }
										 ]
									 }
								 }
							 ]
						 }
					 }
				 ]
			 }
		 }""";

        mappingElasticsearchConverter.updateQuery(criteriaQuery, Person.class);
        var queryString = queryToJson(CriteriaQueryProcessor.createQuery(criteriaQuery.getCriteria()), mapper);

        assertEquals(expected, queryString, false);
    }
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Mar 27, 2025
@sothawo sothawo added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels Apr 4, 2025
sothawo added a commit that referenced this issue Apr 5, 2025
Original Pull Request: #3088
Closes: #3083

Signed-off-by: Peter-Josef Meisch <[email protected]>
@sothawo sothawo added this to the 5.5 RC1 (2025.0.0) milestone Apr 5, 2025
@sothawo
Copy link
Collaborator

sothawo commented Apr 5, 2025

Thanks for finding and reporting. I will backport the fix to the 5.4x and 5.3.x branches as well.

sothawo added a commit that referenced this issue Apr 5, 2025
Original Pull Request: #3088
Closes: #3083

Signed-off-by: Peter-Josef Meisch <[email protected]>
(cherry picked from commit 0e5af90)
sothawo added a commit that referenced this issue Apr 5, 2025
Original Pull Request: #3088
Closes: #3083

Signed-off-by: Peter-Josef Meisch <[email protected]>
(cherry picked from commit 0e5af90)
(cherry picked from commit 46fdc8a)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants