Skip to content

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

Closed
@domenicofasano99

Description

@domenicofasano99

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);
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions