mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-07-28 21:23:28 +00:00
Fix implementation of equlas/hashcode for Criteria class.
Original Pull Request: #3088 Closes: #3083 Signed-off-by: Peter-Josef Meisch <pj.meisch@sothawo.com> (cherry picked from commit 0e5af905818ca852c377c0aa576e56516b713dac)
This commit is contained in:
parent
394fb7a831
commit
46fdc8a84b
@ -22,6 +22,7 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||||
import org.springframework.data.elasticsearch.core.geo.GeoBox;
|
import org.springframework.data.elasticsearch.core.geo.GeoBox;
|
||||||
@ -859,6 +860,7 @@ public class Criteria {
|
|||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
|
// region equals/hashcode
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o)
|
if (this == o)
|
||||||
@ -874,6 +876,8 @@ public class Criteria {
|
|||||||
return false;
|
return false;
|
||||||
if (!Objects.equals(field, criteria.field))
|
if (!Objects.equals(field, criteria.field))
|
||||||
return false;
|
return false;
|
||||||
|
if (!criteriaChain.filter(this).equals(criteria.criteriaChain.filter(criteria)))
|
||||||
|
return false;
|
||||||
if (!queryCriteriaEntries.equals(criteria.queryCriteriaEntries))
|
if (!queryCriteriaEntries.equals(criteria.queryCriteriaEntries))
|
||||||
return false;
|
return false;
|
||||||
if (!filterCriteriaEntries.equals(criteria.filterCriteriaEntries))
|
if (!filterCriteriaEntries.equals(criteria.filterCriteriaEntries))
|
||||||
@ -886,11 +890,16 @@ public class Criteria {
|
|||||||
int result = field != null ? field.hashCode() : 0;
|
int result = field != null ? field.hashCode() : 0;
|
||||||
result = 31 * result + (boost != +0.0f ? Float.floatToIntBits(boost) : 0);
|
result = 31 * result + (boost != +0.0f ? Float.floatToIntBits(boost) : 0);
|
||||||
result = 31 * result + (negating ? 1 : 0);
|
result = 31 * result + (negating ? 1 : 0);
|
||||||
|
// the criteriaChain contains "this" object, so we need to filter it out
|
||||||
|
// to avoid a stackoverflow here, because the hashcode implementation
|
||||||
|
// uses the element's hashcodes
|
||||||
|
result = 31 * result + criteriaChain.filter(this).hashCode();
|
||||||
result = 31 * result + queryCriteriaEntries.hashCode();
|
result = 31 * result + queryCriteriaEntries.hashCode();
|
||||||
result = 31 * result + filterCriteriaEntries.hashCode();
|
result = 31 * result + filterCriteriaEntries.hashCode();
|
||||||
result = 31 * result + subCriteria.hashCode();
|
result = 31 * result + subCriteria.hashCode();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
// endregion
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
@ -938,7 +947,17 @@ public class Criteria {
|
|||||||
*
|
*
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public static class CriteriaChain extends LinkedList<Criteria> {}
|
public static class CriteriaChain extends LinkedList<Criteria> {
|
||||||
|
/**
|
||||||
|
* return a copy of this list with the given element filtered out.
|
||||||
|
*
|
||||||
|
* @param criteria the element to filter
|
||||||
|
* @return the filtered list
|
||||||
|
*/
|
||||||
|
List<Criteria> filter(Criteria criteria) {
|
||||||
|
return this.stream().filter(c -> c != criteria).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Operator to join the entries of the criteria chain
|
* Operator to join the entries of the criteria chain
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.elasticsearch.client.elc;
|
package org.springframework.data.elasticsearch.client.elc;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.*;
|
||||||
import static org.skyscreamer.jsonassert.JSONAssert.*;
|
import static org.skyscreamer.jsonassert.JSONAssert.*;
|
||||||
import static org.springframework.data.elasticsearch.client.elc.JsonUtils.*;
|
import static org.springframework.data.elasticsearch.client.elc.JsonUtils.*;
|
||||||
|
|
||||||
@ -22,6 +23,7 @@ import co.elastic.clients.json.JsonpMapper;
|
|||||||
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
|
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -445,6 +447,108 @@ public class CriteriaQueryMappingUnitTests {
|
|||||||
softly.assertAll();
|
softly.assertAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the following test failed because of a wrong implementation in Criteria
|
||||||
|
// equals and hscode methods.
|
||||||
|
@Test // #3083
|
||||||
|
@DisplayName("should map correct subcriteria")
|
||||||
|
void shouldMapCorrectSubcriteria() 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);
|
||||||
|
}
|
||||||
// endregion
|
// endregion
|
||||||
// region helper functions
|
// region helper functions
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user