Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7c3ea61fa6 | |||
| 0e7845f0e7 | |||
| c9a15acb07 | |||
| c8c0a32f2d | |||
| 98d4cc0d74 | |||
| 1515f33047 | |||
| e0f30b819b | |||
| 2825046949 | |||
| a4defdc5fd | |||
| 039f78e311 | |||
| d93f3c6810 | |||
| b93ed840db | |||
| de956dd81c | |||
| 21306745b3 | |||
| 0f7dc4f54d | |||
| 48855e75df | |||
| 430527504e | |||
| 40cd3f127f | |||
| 2ccf157a58 | |||
| 274df0e9d8 | |||
| b66146dadd | |||
| 930c04e355 | |||
| 4f475575e6 | |||
| 268f73e692 | |||
| 37c20975a9 | |||
| e3afc2b704 | |||
| e634d7ac05 | |||
| 5f1f46acd4 | |||
| 7a5c8b4546 | |||
| ac6dd91b57 |
@@ -0,0 +1,21 @@
|
||||
# GitHub Actions for CodeQL Scanning
|
||||
|
||||
name: "CodeQL Advanced"
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
# https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#schedule
|
||||
- cron: '0 5 * * *'
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
codeql-analysis-call:
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
uses: spring-io/github-actions/.github/workflows/codeql-analysis.yml@1
|
||||
@@ -0,0 +1,45 @@
|
||||
# GitHub Actions to automate GitHub issues for Spring Data Project Management
|
||||
|
||||
name: Spring Data GitHub Issues
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited, reopened]
|
||||
issue_comment:
|
||||
types: [created]
|
||||
pull_request_target:
|
||||
types: [opened, edited, reopened]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
Inbox:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'spring-projects' && (github.event.action == 'opened' || github.event.action == 'reopened') && github.event.pull_request == null && !contains(join(github.event.issue.labels.*.name, ', '), 'dependency-upgrade') && !contains(github.event.issue.title, 'Release ')
|
||||
steps:
|
||||
- name: Create or Update Issue Card
|
||||
uses: actions/add-to-project@v1.0.2
|
||||
with:
|
||||
project-url: https://github.com/orgs/spring-projects/projects/25
|
||||
github-token: ${{ secrets.GH_ISSUES_TOKEN_SPRING_DATA }}
|
||||
Pull-Request:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'spring-projects' && (github.event.action == 'opened' || github.event.action == 'reopened') && github.event.pull_request != null
|
||||
steps:
|
||||
- name: Create or Update Pull Request Card
|
||||
uses: actions/add-to-project@v1.0.2
|
||||
with:
|
||||
project-url: https://github.com/orgs/spring-projects/projects/25
|
||||
github-token: ${{ secrets.GH_ISSUES_TOKEN_SPRING_DATA }}
|
||||
Feedback-Provided:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'spring-projects' && github.event_name == 'issue_comment' && github.event.action == 'created' && github.actor != 'spring-projects-issues' && github.event.pull_request == null && github.event.issue.state == 'open' && contains(toJSON(github.event.issue.labels), 'waiting-for-feedback')
|
||||
steps:
|
||||
- name: Update Project Card
|
||||
uses: actions/add-to-project@v1.0.2
|
||||
with:
|
||||
project-url: https://github.com/orgs/spring-projects/projects/25
|
||||
github-token: ${{ secrets.GH_ISSUES_TOKEN_SPRING_DATA }}
|
||||
+11
-5
@@ -1,9 +1,15 @@
|
||||
# Security Policy
|
||||
= Security Policy
|
||||
|
||||
## Supported Versions
|
||||
== Reporting a Vulnerability
|
||||
|
||||
Please see the https://spring.io/projects/spring-data-elasticsearch[Spring Data Elasticsearch] project page for supported versions.
|
||||
Please, https://github.com/spring-projects/security-advisories/security/advisories/new[open a draft security advisory] if you need to disclose and discuss a security issue in private with the Spring Data team.
|
||||
Note that we only accept reports against https://spring.io/projects/spring-data#support[supported versions].
|
||||
|
||||
## Reporting a Vulnerability
|
||||
For more details, check out our https://spring.io/security-policy[security policy].
|
||||
|
||||
Please don't raise security vulnerabilities here. Head over to https://pivotal.io/security to learn how to disclose them responsibly.
|
||||
== JAR signing
|
||||
|
||||
Spring Data JARs released on Maven Central are signed.
|
||||
You'll find more information about the key here: https://spring.io/GPG-KEY-spring.txt
|
||||
|
||||
Versions released prior to 2023 may be signed with a different key.
|
||||
|
||||
@@ -21,8 +21,8 @@ docker.redis.7.version=7.2.4
|
||||
docker.cassandra.3.version=3.11.16
|
||||
|
||||
# Docker environment settings
|
||||
docker.java.inside.basic=-v $HOME:/tmp/jenkins-home
|
||||
docker.java.inside.docker=-u root -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v $HOME:/tmp/jenkins-home
|
||||
docker.java.inside.basic=-v $HOME:/tmp/jenkins-home --ulimit nofile=32000:32000
|
||||
docker.java.inside.docker=-u root -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v $HOME:/tmp/jenkins-home --ulimit nofile=32000:32000
|
||||
|
||||
# Credentials
|
||||
docker.registry=
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-elasticsearch</artifactId>
|
||||
<version>5.4.8</version>
|
||||
<version>5.4.13</version>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data.build</groupId>
|
||||
<artifactId>spring-data-parent</artifactId>
|
||||
<version>3.4.8</version>
|
||||
<version>3.4.13</version>
|
||||
</parent>
|
||||
|
||||
<name>Spring Data Elasticsearch</name>
|
||||
@@ -18,7 +18,7 @@
|
||||
<url>https://github.com/spring-projects/spring-data-elasticsearch</url>
|
||||
|
||||
<properties>
|
||||
<springdata.commons>3.4.8</springdata.commons>
|
||||
<springdata.commons>3.4.13</springdata.commons>
|
||||
|
||||
<!-- version of the ElasticsearchClient -->
|
||||
<elasticsearch-java>8.15.5</elasticsearch-java>
|
||||
@@ -41,6 +41,15 @@
|
||||
</properties>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>sothawo</id>
|
||||
<name>Peter-Josef Meisch</name>
|
||||
<email>pj.meisch at sothawo.com</email>
|
||||
<roles>
|
||||
<role>Project Lead</role>
|
||||
</roles>
|
||||
<timezone>+1</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>biomedcentral</id>
|
||||
<name>BioMed Central Development Team</name>
|
||||
@@ -77,11 +86,6 @@
|
||||
</developerConnection>
|
||||
</scm>
|
||||
|
||||
<ciManagement>
|
||||
<system>Bamboo</system>
|
||||
<url>https://build.spring.io/browse/SPRINGDATAES</url>
|
||||
</ciManagement>
|
||||
|
||||
<issueManagement>
|
||||
<system>GitHub</system>
|
||||
<url>https://github.com/spring-projects/spring-data-elasticsearch/issues</url>
|
||||
|
||||
+3
-3
@@ -367,7 +367,7 @@ would make an https://www.elastic.co/guide/en/elasticsearch/reference/current/qu
|
||||
|
||||
.Declare query on the method using the `@Query` annotation with SpEL expression.
|
||||
====
|
||||
https://docs.spring.io/spring-framework/reference/core/expressions.html[SpEL expression] is also supported when defining query in `@Query`.
|
||||
{spring-framework-docs}/core/expressions.html[SpEL expression] is also supported when defining query in `@Query`.
|
||||
|
||||
|
||||
[source,java]
|
||||
@@ -444,7 +444,7 @@ We can pass `new QueryParameter("John")` as the parameter now, and it will produ
|
||||
|
||||
.accessing bean property.
|
||||
====
|
||||
https://docs.spring.io/spring-framework/reference/core/expressions/language-ref/bean-references.html[Bean property] is also supported to access. Given that there is a bean named `queryParameter` of type `QueryParameter`, we can access the bean with symbol `@` rather than `#`, and there is no need to declare a parameter of type `QueryParameter` in the query method:
|
||||
{spring-framework-docs}/core/expressions/language-ref/bean-references.html[Bean property] is also supported to access. Given that there is a bean named `queryParameter` of type `QueryParameter`, we can access the bean with symbol `@` rather than `#`, and there is no need to declare a parameter of type `QueryParameter` in the query method:
|
||||
[source,java]
|
||||
----
|
||||
interface BookRepository extends ElasticsearchRepository<Book, String> {
|
||||
@@ -511,7 +511,7 @@ A collection of `names` like `List.of("name1", "name2")` will produce the follow
|
||||
|
||||
.access property in the `Collection` param.
|
||||
====
|
||||
https://docs.spring.io/spring-framework/reference/core/expressions/language-ref/collection-projection.html[SpEL Collection Projection] is convenient to use when values in the `Collection` parameter is not plain `String`:
|
||||
{spring-framework-docs}/core/expressions/language-ref/collection-projection.html[SpEL Collection Projection] is convenient to use when values in the `Collection` parameter is not plain `String`:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
|
||||
@@ -3,19 +3,20 @@ prerelease: ${antora-component.prerelease}
|
||||
|
||||
asciidoc:
|
||||
attributes:
|
||||
copyright-year: ${current.year}
|
||||
version: ${project.version}
|
||||
springversionshort: ${spring.short}
|
||||
springversion: ${spring}
|
||||
attribute-missing: 'warn'
|
||||
commons: ${springdata.commons.docs}
|
||||
chomp: 'all'
|
||||
version: '${project.version}'
|
||||
copyright-year: '${current.year}'
|
||||
springversionshort: '${spring.short}'
|
||||
springversion: '${spring}'
|
||||
commons: '${springdata.commons.docs}'
|
||||
include-xml-namespaces: false
|
||||
spring-data-commons-docs-url: https://docs.spring.io/spring-data/commons/reference
|
||||
spring-data-commons-javadoc-base: https://docs.spring.io/spring-data/commons/docs/${springdata.commons}/api/
|
||||
springdocsurl: https://docs.spring.io/spring-framework/reference/{springversionshort}
|
||||
springjavadocurl: https://docs.spring.io/spring-framework/docs/${spring}/javadoc-api
|
||||
spring-data-commons-docs-url: '${documentation.baseurl}/spring-data/commons/reference/${springdata.commons.short}'
|
||||
spring-data-commons-javadoc-base: '{spring-data-commons-docs-url}/api/java'
|
||||
springdocsurl: '${documentation.baseurl}/spring-framework/reference/{springversionshort}'
|
||||
spring-framework-docs: '{springdocsurl}'
|
||||
springjavadocurl: '${documentation.spring-javadoc-url}'
|
||||
spring-framework-javadoc: '{springjavadocurl}'
|
||||
springhateoasversion: ${spring-hateoas}
|
||||
releasetrainversion: ${releasetrain}
|
||||
springhateoasversion: '${spring-hateoas}'
|
||||
releasetrainversion: '${releasetrain}'
|
||||
store: Elasticsearch
|
||||
|
||||
@@ -436,7 +436,7 @@ final class TypeUtils {
|
||||
// values taken from the RHLC implementation
|
||||
if (value == null) {
|
||||
return -2;
|
||||
} else if ("all".equals(value.toUpperCase())) {
|
||||
} else if ("all".equals(value.toLowerCase())) {
|
||||
return -1;
|
||||
} else {
|
||||
try {
|
||||
|
||||
@@ -61,12 +61,16 @@ public class Criteria {
|
||||
private float boost = Float.NaN;
|
||||
private boolean negating = false;
|
||||
|
||||
private final CriteriaChain criteriaChain = new CriteriaChain();
|
||||
private final Set<CriteriaEntry> queryCriteriaEntries = new LinkedHashSet<>();
|
||||
private final Set<CriteriaEntry> filterCriteriaEntries = new LinkedHashSet<>();
|
||||
private final Set<Criteria> subCriteria = new LinkedHashSet<>();
|
||||
// we cash this and recalculate when properties used in equals change
|
||||
// see https://github.com/spring-projects/spring-data-elasticsearch/issues/3083
|
||||
private int hashCode;
|
||||
|
||||
// region criteria creation
|
||||
private final CriteriaChain criteriaChain = new CriteriaChain();
|
||||
private final Set<CriteriaEntry> queryCriteriaEntries = new LinkedHashSet<>();
|
||||
private final Set<CriteriaEntry> filterCriteriaEntries = new LinkedHashSet<>();
|
||||
private final Set<Criteria> subCriteria = new LinkedHashSet<>();
|
||||
|
||||
// region criteria creation
|
||||
|
||||
/**
|
||||
* @return factory method to create an and-Criteria that is not bound to a field
|
||||
@@ -84,7 +88,9 @@ public class Criteria {
|
||||
return new OrCriteria();
|
||||
}
|
||||
|
||||
public Criteria() {}
|
||||
public Criteria() {
|
||||
recalculateHashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Criteria with provided field name
|
||||
@@ -107,6 +113,7 @@ public class Criteria {
|
||||
|
||||
this.field = field;
|
||||
this.criteriaChain.add(this);
|
||||
recalculateHashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -136,6 +143,7 @@ public class Criteria {
|
||||
this.field = field;
|
||||
this.criteriaChain.addAll(criteriaChain);
|
||||
this.criteriaChain.add(this);
|
||||
recalculateHashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,6 +197,7 @@ public class Criteria {
|
||||
*/
|
||||
public Criteria not() {
|
||||
this.negating = true;
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -207,6 +216,7 @@ public class Criteria {
|
||||
Assert.isTrue(boost >= 0, "boost must not be negative");
|
||||
|
||||
this.boost = boost;
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -223,7 +233,7 @@ public class Criteria {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the set ob subCriteria
|
||||
* @return the set of subCriteria
|
||||
* @since 4.1
|
||||
*/
|
||||
public Set<Criteria> getSubCriteria() {
|
||||
@@ -264,6 +274,7 @@ public class Criteria {
|
||||
Assert.notNull(criteria, "Cannot chain 'null' criteria.");
|
||||
|
||||
this.criteriaChain.add(criteria);
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -278,6 +289,7 @@ public class Criteria {
|
||||
Assert.notNull(criterias, "Cannot chain 'null' criterias.");
|
||||
|
||||
this.criteriaChain.addAll(Arrays.asList(criterias));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -320,6 +332,7 @@ public class Criteria {
|
||||
orCriteria.subCriteria.addAll(criteria.subCriteria);
|
||||
orCriteria.boost = criteria.boost;
|
||||
orCriteria.negating = criteria.isNegating();
|
||||
orCriteria.recalculateHashCode();
|
||||
return orCriteria;
|
||||
}
|
||||
|
||||
@@ -335,6 +348,7 @@ public class Criteria {
|
||||
Assert.notNull(criteria, "criteria must not be null");
|
||||
|
||||
subCriteria.add(criteria);
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -349,6 +363,7 @@ public class Criteria {
|
||||
*/
|
||||
public Criteria is(Object o) {
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.EQUALS, o));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -360,6 +375,7 @@ public class Criteria {
|
||||
*/
|
||||
public Criteria exists() {
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.EXISTS));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -378,6 +394,7 @@ public class Criteria {
|
||||
}
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.BETWEEN, new Object[] { lowerBound, upperBound }));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -393,6 +410,7 @@ public class Criteria {
|
||||
|
||||
assertNoBlankInWildcardQuery(s, false, true);
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.STARTS_WITH, s));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -409,6 +427,7 @@ public class Criteria {
|
||||
|
||||
assertNoBlankInWildcardQuery(s, true, true);
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.CONTAINS, s));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -425,6 +444,7 @@ public class Criteria {
|
||||
|
||||
assertNoBlankInWildcardQuery(s, true, false);
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.ENDS_WITH, s));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -452,6 +472,7 @@ public class Criteria {
|
||||
Assert.notNull(values, "Collection of 'in' values must not be null");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.IN, values));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -478,6 +499,7 @@ public class Criteria {
|
||||
Assert.notNull(values, "Collection of 'NotIn' values must not be null");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.NOT_IN, values));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -490,6 +512,7 @@ public class Criteria {
|
||||
*/
|
||||
public Criteria expression(String s) {
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.EXPRESSION, s));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -501,6 +524,7 @@ public class Criteria {
|
||||
*/
|
||||
public Criteria fuzzy(String s) {
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.FUZZY, s));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -515,6 +539,7 @@ public class Criteria {
|
||||
Assert.notNull(upperBound, "upperBound must not be null");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.LESS_EQUAL, upperBound));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -529,6 +554,7 @@ public class Criteria {
|
||||
Assert.notNull(upperBound, "upperBound must not be null");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.LESS, upperBound));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -543,6 +569,7 @@ public class Criteria {
|
||||
Assert.notNull(lowerBound, "lowerBound must not be null");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.GREATER_EQUAL, lowerBound));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -557,6 +584,7 @@ public class Criteria {
|
||||
Assert.notNull(lowerBound, "lowerBound must not be null");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.GREATER, lowerBound));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -573,6 +601,7 @@ public class Criteria {
|
||||
Assert.notNull(value, "value must not be null");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.MATCHES, value));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -589,6 +618,7 @@ public class Criteria {
|
||||
Assert.notNull(value, "value must not be null");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.MATCHES_ALL, value));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -601,6 +631,7 @@ public class Criteria {
|
||||
public Criteria empty() {
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.EMPTY));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -613,6 +644,7 @@ public class Criteria {
|
||||
public Criteria notEmpty() {
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.NOT_EMPTY));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -628,6 +660,7 @@ public class Criteria {
|
||||
Assert.notNull(value, "value must not be null");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.REGEXP, value));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -646,6 +679,7 @@ public class Criteria {
|
||||
Assert.notNull(boundingBox, "boundingBox value for boundedBy criteria must not be null");
|
||||
|
||||
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { boundingBox }));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -662,6 +696,7 @@ public class Criteria {
|
||||
|
||||
filterCriteriaEntries
|
||||
.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { boundingBox.getFirst(), boundingBox.getSecond() }));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -679,6 +714,7 @@ public class Criteria {
|
||||
|
||||
filterCriteriaEntries
|
||||
.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { topLeftGeohash, bottomRightGeohash }));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -695,6 +731,7 @@ public class Criteria {
|
||||
Assert.notNull(bottomRightPoint, "bottomRightPoint must not be null");
|
||||
|
||||
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { topLeftPoint, bottomRightPoint }));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -712,6 +749,7 @@ public class Criteria {
|
||||
|
||||
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.BBOX,
|
||||
new Object[] { GeoPoint.fromPoint(topLeftPoint), GeoPoint.fromPoint(bottomRightPoint) }));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -729,6 +767,7 @@ public class Criteria {
|
||||
Assert.notNull(location, "Distance value for near criteria must not be null");
|
||||
|
||||
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { location, distance }));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -745,6 +784,7 @@ public class Criteria {
|
||||
Assert.notNull(location, "Distance value for near criteria must not be null");
|
||||
|
||||
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { location, distance }));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -761,6 +801,7 @@ public class Criteria {
|
||||
Assert.isTrue(StringUtils.hasLength(geoLocation), "geoLocation value must not be null");
|
||||
|
||||
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { geoLocation, distance }));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -775,6 +816,7 @@ public class Criteria {
|
||||
Assert.notNull(geoShape, "geoShape must not be null");
|
||||
|
||||
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.GEO_INTERSECTS, geoShape));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -789,6 +831,7 @@ public class Criteria {
|
||||
Assert.notNull(geoShape, "geoShape must not be null");
|
||||
|
||||
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.GEO_IS_DISJOINT, geoShape));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -802,6 +845,7 @@ public class Criteria {
|
||||
Assert.notNull(geoShape, "geoShape must not be null");
|
||||
|
||||
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.GEO_WITHIN, geoShape));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -815,6 +859,7 @@ public class Criteria {
|
||||
Assert.notNull(geoShape, "geoShape must not be null");
|
||||
|
||||
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.GEO_CONTAINS, geoShape));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -828,6 +873,7 @@ public class Criteria {
|
||||
Assert.notNull(query, "has_child query must not be null.");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.HAS_CHILD, query));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -841,6 +887,7 @@ public class Criteria {
|
||||
Assert.notNull(query, "has_parent query must not be null.");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.HAS_PARENT, query));
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
// endregion
|
||||
@@ -887,18 +934,22 @@ public class Criteria {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = field != null ? field.hashCode() : 0;
|
||||
result = 31 * result + (boost != +0.0f ? Float.floatToIntBits(boost) : 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 + filterCriteriaEntries.hashCode();
|
||||
result = 31 * result + subCriteria.hashCode();
|
||||
return result;
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
private void recalculateHashCode() {
|
||||
int result = field != null ? field.hashCode() : 0;
|
||||
result = 31 * result + (boost != +0.0f ? Float.floatToIntBits(boost) : 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 + filterCriteriaEntries.hashCode();
|
||||
result = 31 * result + subCriteria.hashCode();
|
||||
this.hashCode = result;
|
||||
}
|
||||
// endregion
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Spring Data Elasticsearch 5.4.8 (2024.1.8)
|
||||
Spring Data Elasticsearch 5.4.13 (2024.1.13)
|
||||
Copyright (c) [2013-2022] Pivotal Software, Inc.
|
||||
|
||||
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||
@@ -27,6 +27,11 @@ conditions of the subcomponent's license, as noted in the LICENSE file.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -448,7 +448,7 @@ public class CriteriaQueryMappingUnitTests {
|
||||
}
|
||||
|
||||
// the following test failed because of a wrong implementation in Criteria
|
||||
// equals and hscode methods.
|
||||
// equals and hashcode methods.
|
||||
@Test // #3083
|
||||
@DisplayName("should map correct subcriteria")
|
||||
void shouldMapCorrectSubcriteria() throws JSONException {
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2019-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.core.query;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* @author Peter-Josef Meisch
|
||||
*/
|
||||
class CriteriaTest {
|
||||
|
||||
@Test // #3159
|
||||
@DisplayName("should not slow down on calculating hashcode for long criteria chains")
|
||||
void shouldNotSlowDownOnCalculatingHashcodeForLongCriteriaChains() {
|
||||
assertTimeoutPreemptively(Duration.of(1, ChronoUnit.SECONDS), () -> {
|
||||
var criteria = new Criteria();
|
||||
var size = 1000;
|
||||
for (int i = 1; i <= size; i++) {
|
||||
criteria = criteria.or("field-" + i).contains("value-" + i);
|
||||
}
|
||||
final var criteriaChain = criteria.getCriteriaChain();
|
||||
assertEquals(size, criteriaChain.size());
|
||||
final var hashCode = Integer.valueOf(criteria.hashCode());
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
api.version=1.44
|
||||
Reference in New Issue
Block a user