mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-06-28 06:42:29 +00:00
DATAES-799 - Polishing.
This commit is contained in:
parent
9b620b31bd
commit
15f51c5151
@ -79,8 +79,7 @@ public class ElasticsearchExceptionTranslator implements PersistenceExceptionTra
|
|||||||
|
|
||||||
if (exception instanceof ElasticsearchStatusException) {
|
if (exception instanceof ElasticsearchStatusException) {
|
||||||
ElasticsearchStatusException statusException = (ElasticsearchStatusException) exception;
|
ElasticsearchStatusException statusException = (ElasticsearchStatusException) exception;
|
||||||
return statusException.status() == RestStatus.CONFLICT
|
return statusException.status() == RestStatus.CONFLICT && statusException.getMessage() != null
|
||||||
&& statusException.getMessage() != null
|
|
||||||
&& statusException.getMessage().contains("type=version_conflict_engine_exception")
|
&& statusException.getMessage().contains("type=version_conflict_engine_exception")
|
||||||
&& statusException.getMessage().contains("version conflict, required seqNo");
|
&& statusException.getMessage().contains("version conflict, required seqNo");
|
||||||
}
|
}
|
||||||
|
@ -272,7 +272,8 @@ class EntityOperations {
|
|||||||
*
|
*
|
||||||
* @return SeqNoPrimaryTerm, may be {@literal null}
|
* @return SeqNoPrimaryTerm, may be {@literal null}
|
||||||
*/
|
*/
|
||||||
@Nullable SeqNoPrimaryTerm getSeqNoPrimaryTerm();
|
@Nullable
|
||||||
|
SeqNoPrimaryTerm getSeqNoPrimaryTerm();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -709,7 +709,8 @@ class RequestFactory {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ElasticsearchPersistentEntity<?> entity = elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(entityClass);
|
ElasticsearchPersistentEntity<?> entity = elasticsearchConverter.getMappingContext()
|
||||||
|
.getRequiredPersistentEntity(entityClass);
|
||||||
return entity.hasSeqNoPrimaryTermProperty();
|
return entity.hasSeqNoPrimaryTermProperty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.elasticsearch.core.convert;
|
package org.springframework.data.elasticsearch.core.convert;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
@ -297,7 +306,8 @@ public class MappingElasticsearchConverter
|
|||||||
if (value instanceof List) {
|
if (value instanceof List) {
|
||||||
target.add(readValue(value, property, property.getTypeInformation().getActualType()));
|
target.add(readValue(value, property, property.getTypeInformation().getActualType()));
|
||||||
} else if (value instanceof Map) {
|
} else if (value instanceof Map) {
|
||||||
target.add(readMapValue((Map<String, Object>) value, property, property.getTypeInformation().getActualType()));
|
target
|
||||||
|
.add(readMapValue((Map<String, Object>) value, property, property.getTypeInformation().getActualType()));
|
||||||
} else {
|
} else {
|
||||||
target.add(readEntity(computeGenericValueTypeForRead(property, value), (Map<String, Object>) value));
|
target.add(readEntity(computeGenericValueTypeForRead(property, value), (Map<String, Object>) value));
|
||||||
}
|
}
|
||||||
|
@ -182,8 +182,8 @@ public interface Document extends Map<String, Object> {
|
|||||||
* {@link #hasSeqNo()} prior to calling this method.
|
* {@link #hasSeqNo()} prior to calling this method.
|
||||||
*
|
*
|
||||||
* @return the seq_no associated with this {@link Document}.
|
* @return the seq_no associated with this {@link Document}.
|
||||||
* @throws IllegalStateException if the underlying implementation supports seq_no's but no seq_no was yet
|
* @throws IllegalStateException if the underlying implementation supports seq_no's but no seq_no was yet associated
|
||||||
* associated with the document.
|
* with the document.
|
||||||
*/
|
*/
|
||||||
default long getSeqNo() {
|
default long getSeqNo() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
@ -214,8 +214,8 @@ public interface Document extends Map<String, Object> {
|
|||||||
* {@link #hasPrimaryTerm()} prior to calling this method.
|
* {@link #hasPrimaryTerm()} prior to calling this method.
|
||||||
*
|
*
|
||||||
* @return the primary_term associated with this {@link Document}.
|
* @return the primary_term associated with this {@link Document}.
|
||||||
* @throws IllegalStateException if the underlying implementation supports primary_term's but no primary_term was
|
* @throws IllegalStateException if the underlying implementation supports primary_term's but no primary_term was yet
|
||||||
* yet associated with the document.
|
* associated with the document.
|
||||||
*/
|
*/
|
||||||
default long getPrimaryTerm() {
|
default long getPrimaryTerm() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
@ -77,8 +77,8 @@ public class DocumentAdapters {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (source.isSourceEmpty()) {
|
if (source.isSourceEmpty()) {
|
||||||
return fromDocumentFields(source, source.getId(), source.getVersion(),
|
return fromDocumentFields(source, source.getId(), source.getVersion(), source.getSeqNo(),
|
||||||
source.getSeqNo(), source.getPrimaryTerm());
|
source.getPrimaryTerm());
|
||||||
}
|
}
|
||||||
|
|
||||||
Document document = Document.from(source.getSourceAsMap());
|
Document document = Document.from(source.getSourceAsMap());
|
||||||
@ -108,8 +108,8 @@ public class DocumentAdapters {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (source.isSourceEmpty()) {
|
if (source.isSourceEmpty()) {
|
||||||
return fromDocumentFields(source, source.getId(), source.getVersion(),
|
return fromDocumentFields(source, source.getId(), source.getVersion(), source.getSeqNo(),
|
||||||
source.getSeqNo(), source.getPrimaryTerm());
|
source.getPrimaryTerm());
|
||||||
}
|
}
|
||||||
|
|
||||||
Document document = Document.from(source.getSource());
|
Document document = Document.from(source.getSource());
|
||||||
@ -157,8 +157,7 @@ public class DocumentAdapters {
|
|||||||
|
|
||||||
if (sourceRef == null || sourceRef.length() == 0) {
|
if (sourceRef == null || sourceRef.length() == 0) {
|
||||||
return new SearchDocumentAdapter(source.getScore(), source.getSortValues(), source.getFields(), highlightFields,
|
return new SearchDocumentAdapter(source.getScore(), source.getSortValues(), source.getFields(), highlightFields,
|
||||||
fromDocumentFields(source, source.getId(), source.getVersion(),
|
fromDocumentFields(source, source.getId(), source.getVersion(), source.getSeqNo(), source.getPrimaryTerm()));
|
||||||
source.getSeqNo(), source.getPrimaryTerm()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Document document = Document.from(source.getSourceAsMap());
|
Document document = Document.from(source.getSourceAsMap());
|
||||||
@ -180,8 +179,8 @@ public class DocumentAdapters {
|
|||||||
* @param documentFields the {@link DocumentField}s backing the {@link Document}.
|
* @param documentFields the {@link DocumentField}s backing the {@link Document}.
|
||||||
* @return the adapted {@link Document}.
|
* @return the adapted {@link Document}.
|
||||||
*/
|
*/
|
||||||
public static Document fromDocumentFields(Iterable<DocumentField> documentFields, String id, long version,
|
public static Document fromDocumentFields(Iterable<DocumentField> documentFields, String id, long version, long seqNo,
|
||||||
long seqNo, long primaryTerm) {
|
long primaryTerm) {
|
||||||
|
|
||||||
if (documentFields instanceof Collection) {
|
if (documentFields instanceof Collection) {
|
||||||
return new DocumentFieldAdapter((Collection<DocumentField>) documentFields, id, version, seqNo, primaryTerm);
|
return new DocumentFieldAdapter((Collection<DocumentField>) documentFields, id, version, seqNo, primaryTerm);
|
||||||
@ -204,8 +203,8 @@ public class DocumentAdapters {
|
|||||||
private final long seqNo;
|
private final long seqNo;
|
||||||
private final long primaryTerm;
|
private final long primaryTerm;
|
||||||
|
|
||||||
DocumentFieldAdapter(Collection<DocumentField> documentFields, String id, long version,
|
DocumentFieldAdapter(Collection<DocumentField> documentFields, String id, long version, long seqNo,
|
||||||
long seqNo, long primaryTerm) {
|
long primaryTerm) {
|
||||||
this.documentFields = documentFields;
|
this.documentFields = documentFields;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.version = version;
|
this.version = version;
|
||||||
|
@ -60,7 +60,8 @@ public interface ElasticsearchPersistentEntity<T> extends PersistentEntity<T, El
|
|||||||
|
|
||||||
String settingPath();
|
String settingPath();
|
||||||
|
|
||||||
@Nullable VersionType getVersionType();
|
@Nullable
|
||||||
|
VersionType getVersionType();
|
||||||
|
|
||||||
boolean isCreateIndexAndMapping();
|
boolean isCreateIndexAndMapping();
|
||||||
|
|
||||||
@ -109,8 +110,8 @@ public interface ElasticsearchPersistentEntity<T> extends PersistentEntity<T, El
|
|||||||
boolean hasSeqNoPrimaryTermProperty();
|
boolean hasSeqNoPrimaryTermProperty();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link SeqNoPrimaryTerm} property of the {@link ElasticsearchPersistentEntity}. Can be
|
* Returns the {@link SeqNoPrimaryTerm} property of the {@link ElasticsearchPersistentEntity}. Can be {@literal null}
|
||||||
* {@literal null} in case no such property is available on the entity.
|
* in case no such property is available on the entity.
|
||||||
*
|
*
|
||||||
* @return the {@link SeqNoPrimaryTerm} {@link ElasticsearchPersistentProperty} of the {@link PersistentEntity} or
|
* @return the {@link SeqNoPrimaryTerm} {@link ElasticsearchPersistentProperty} of the {@link PersistentEntity} or
|
||||||
* {@literal null} if not defined.
|
* {@literal null} if not defined.
|
||||||
@ -131,8 +132,8 @@ public interface ElasticsearchPersistentEntity<T> extends PersistentEntity<T, El
|
|||||||
if (property != null) {
|
if (property != null) {
|
||||||
return property;
|
return property;
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException(String.format("Required SeqNoPrimaryTerm property not found for %s!",
|
throw new IllegalStateException(
|
||||||
this.getType()));
|
String.format("Required SeqNoPrimaryTerm property not found for %s!", this.getType()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,8 +43,8 @@ public interface ElasticsearchPersistentProperty extends PersistentProperty<Elas
|
|||||||
* Returns whether the current property is a <em>potential</em> score property of the owning
|
* Returns whether the current property is a <em>potential</em> score property of the owning
|
||||||
* {@link ElasticsearchPersistentEntity}. This method is mainly used by {@link ElasticsearchPersistentEntity}
|
* {@link ElasticsearchPersistentEntity}. This method is mainly used by {@link ElasticsearchPersistentEntity}
|
||||||
* implementation to discover score property candidates on {@link ElasticsearchPersistentEntity} creation you should
|
* implementation to discover score property candidates on {@link ElasticsearchPersistentEntity} creation you should
|
||||||
* rather call {@link ElasticsearchPersistentEntity#getScoreProperty()} to determine whether the
|
* rather call {@link ElasticsearchPersistentEntity#getScoreProperty()} to determine whether the current property is
|
||||||
* current property is the score property of that {@link ElasticsearchPersistentEntity} under consideration.
|
* the score property of that {@link ElasticsearchPersistentEntity} under consideration.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
|
@ -18,21 +18,25 @@ package org.springframework.data.elasticsearch.core.query;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>A container for seq_no and primary_term values. When an entity class contains a field of this type,
|
* <p>
|
||||||
* it will be automatically filled with SeqNoPrimaryTerm instance on read operations (like get or search),
|
* A container for seq_no and primary_term values. When an entity class contains a field of this type, it will be
|
||||||
* and also, when the SeqNoPrimaryTerm is not {@literal null} and filled with seq_no and primary_term,
|
* automatically filled with SeqNoPrimaryTerm instance on read operations (like get or search), and also, when the
|
||||||
* they will be sent to Elasticsearch when indexing such an entity.
|
* SeqNoPrimaryTerm is not {@literal null} and filled with seq_no and primary_term, they will be sent to Elasticsearch
|
||||||
|
* when indexing such an entity.
|
||||||
* </p>
|
* </p>
|
||||||
* <p>This allows to implement optimistic locking pattern for full-update scenario, when an entity is first
|
* <p>
|
||||||
* read from Elasticsearch and then gets reindexed with new _content.
|
* This allows to implement optimistic locking pattern for full-update scenario, when an entity is first read from
|
||||||
* Index operations will throw an {@link org.springframework.dao.OptimisticLockingFailureException} if the
|
* Elasticsearch and then gets reindexed with new _content. Index operations will throw an
|
||||||
* seq_no + primary_term pair already has different values for the given document. See Elasticsearch documentation
|
* {@link org.springframework.dao.OptimisticLockingFailureException} if the seq_no + primary_term pair already has
|
||||||
* for more information: https://www.elastic.co/guide/en/elasticsearch/reference/current/optimistic-concurrency-control.html
|
* different values for the given document. See Elasticsearch documentation for more information:
|
||||||
|
* https://www.elastic.co/guide/en/elasticsearch/reference/current/optimistic-concurrency-control.html
|
||||||
* </p>
|
* </p>
|
||||||
* <p>A property of this type is implicitly @{@link org.springframework.data.annotation.Transient} and never gets included
|
* <p>
|
||||||
|
* A property of this type is implicitly @{@link org.springframework.data.annotation.Transient} and never gets included
|
||||||
* into a mapping at Elasticsearch side.
|
* into a mapping at Elasticsearch side.
|
||||||
* </p>
|
* </p>
|
||||||
* <p>A SeqNoPrimaryTerm instance cannot contain an invalid or unassigned seq_no or primary_term.
|
* <p>
|
||||||
|
* A SeqNoPrimaryTerm instance cannot contain an invalid or unassigned seq_no or primary_term.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Roman Puchkovskiy
|
* @author Roman Puchkovskiy
|
||||||
@ -44,8 +48,8 @@ public final class SeqNoPrimaryTerm {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance of SeqNoPrimaryTerm with the given seq_no and primary_term. The passed values are validated:
|
* Creates an instance of SeqNoPrimaryTerm with the given seq_no and primary_term. The passed values are validated:
|
||||||
* sequenceNumber must be non-negative, primaryTerm must be positive. If validation fails,
|
* sequenceNumber must be non-negative, primaryTerm must be positive. If validation fails, an IllegalArgumentException
|
||||||
* an IllegalArgumentException is thrown.
|
* is thrown.
|
||||||
*
|
*
|
||||||
* @param sequenceNumber seq_no, must not be negative
|
* @param sequenceNumber seq_no, must not be negative
|
||||||
* @param primaryTerm primary_term, must be positive
|
* @param primaryTerm primary_term, must be positive
|
||||||
@ -73,10 +77,7 @@ public final class SeqNoPrimaryTerm {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "SeqNoPrimaryTerm{" +
|
return "SeqNoPrimaryTerm{" + "sequenceNumber=" + sequenceNumber + ", primaryTerm=" + primaryTerm + '}';
|
||||||
"sequenceNumber=" + sequenceNumber +
|
|
||||||
", primaryTerm=" + primaryTerm +
|
|
||||||
'}';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -88,8 +89,7 @@ public final class SeqNoPrimaryTerm {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
SeqNoPrimaryTerm that = (SeqNoPrimaryTerm) o;
|
SeqNoPrimaryTerm that = (SeqNoPrimaryTerm) o;
|
||||||
return sequenceNumber == that.sequenceNumber &&
|
return sequenceNumber == that.sequenceNumber && primaryTerm == that.primaryTerm;
|
||||||
primaryTerm == that.primaryTerm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -25,8 +25,6 @@ import org.junit.jupiter.api.Test;
|
|||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.dao.OptimisticLockingFailureException;
|
import org.springframework.dao.OptimisticLockingFailureException;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Roman Puchkovskiy
|
* @author Roman Puchkovskiy
|
||||||
*/
|
*/
|
||||||
@ -48,8 +46,8 @@ class ElasticsearchExceptionTranslatorTests {
|
|||||||
|
|
||||||
@Test // DATAES-799
|
@Test // DATAES-799
|
||||||
void shouldConvertVersionConflictEngineExceptionWithSeqNoConflictToOptimisticLockingFailureException() {
|
void shouldConvertVersionConflictEngineExceptionWithSeqNoConflictToOptimisticLockingFailureException() {
|
||||||
VersionConflictEngineException ex = new VersionConflictEngineException(
|
VersionConflictEngineException ex = new VersionConflictEngineException(new ShardId("index", "uuid", 1),
|
||||||
new ShardId("index", "uuid", 1), "exception-id",
|
"exception-id",
|
||||||
"Elasticsearch exception [type=version_conflict_engine_exception, reason=[WPUUsXEB6uuA6j8_A7AB]: version conflict, required seqNo [34], primary term [16]. current document has seqNo [35] and primary term [16]]");
|
"Elasticsearch exception [type=version_conflict_engine_exception, reason=[WPUUsXEB6uuA6j8_A7AB]: version conflict, required seqNo [34], primary term [16]. current document has seqNo [35] and primary term [16]]");
|
||||||
|
|
||||||
DataAccessException translated = translator.translateExceptionIfPossible(ex);
|
DataAccessException translated = translator.translateExceptionIfPossible(ex);
|
||||||
|
@ -62,7 +62,16 @@ import org.springframework.data.elasticsearch.annotations.Field;
|
|||||||
import org.springframework.data.elasticsearch.annotations.Score;
|
import org.springframework.data.elasticsearch.annotations.Score;
|
||||||
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
|
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
|
||||||
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
|
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
|
||||||
import org.springframework.data.elasticsearch.core.query.*;
|
import org.springframework.data.elasticsearch.core.query.Criteria;
|
||||||
|
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
|
||||||
|
import org.springframework.data.elasticsearch.core.query.IndexQuery;
|
||||||
|
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
|
||||||
|
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
|
||||||
|
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
|
||||||
|
import org.springframework.data.elasticsearch.core.query.Query;
|
||||||
|
import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm;
|
||||||
|
import org.springframework.data.elasticsearch.core.query.StringQuery;
|
||||||
|
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
|
||||||
import org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersion;
|
import org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersion;
|
||||||
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
|
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
@ -858,10 +867,8 @@ public class ReactiveElasticsearchTemplateTests {
|
|||||||
original.setMessage("It's fine");
|
original.setMessage("It's fine");
|
||||||
OptimisticEntity saved = template.save(original).block();
|
OptimisticEntity saved = template.save(original).block();
|
||||||
|
|
||||||
template.get(saved.getId(), OptimisticEntity.class)
|
template.get(saved.getId(), OptimisticEntity.class).as(StepVerifier::create)
|
||||||
.as(StepVerifier::create)
|
.assertNext(this::assertThatSeqNoPrimaryTermIsFilled).verifyComplete();
|
||||||
.assertNext(this::assertThatSeqNoPrimaryTermIsFilled)
|
|
||||||
.verifyComplete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertThatSeqNoPrimaryTermIsFilled(OptimisticEntity retrieved) {
|
private void assertThatSeqNoPrimaryTermIsFilled(OptimisticEntity retrieved) {
|
||||||
@ -878,10 +885,10 @@ public class ReactiveElasticsearchTemplateTests {
|
|||||||
original.setMessage("It's fine");
|
original.setMessage("It's fine");
|
||||||
OptimisticEntity saved = template.save(original).block();
|
OptimisticEntity saved = template.save(original).block();
|
||||||
|
|
||||||
template.multiGet(multiGetQueryForOne(saved.getId()), OptimisticEntity.class, template.getIndexCoordinatesFor(OptimisticEntity.class))
|
template
|
||||||
.as(StepVerifier::create)
|
.multiGet(multiGetQueryForOne(saved.getId()), OptimisticEntity.class,
|
||||||
.assertNext(this::assertThatSeqNoPrimaryTermIsFilled)
|
template.getIndexCoordinatesFor(OptimisticEntity.class))
|
||||||
.verifyComplete();
|
.as(StepVerifier::create).assertNext(this::assertThatSeqNoPrimaryTermIsFilled).verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Query multiGetQueryForOne(String id) {
|
private Query multiGetQueryForOne(String id) {
|
||||||
@ -895,17 +902,15 @@ public class ReactiveElasticsearchTemplateTests {
|
|||||||
OptimisticEntity saved = template.save(original).block();
|
OptimisticEntity saved = template.save(original).block();
|
||||||
restTemplate.refresh(OptimisticEntity.class);
|
restTemplate.refresh(OptimisticEntity.class);
|
||||||
|
|
||||||
template.search(searchQueryForOne(saved.getId()), OptimisticEntity.class, template.getIndexCoordinatesFor(OptimisticEntity.class))
|
template
|
||||||
.map(SearchHit::getContent)
|
.search(searchQueryForOne(saved.getId()), OptimisticEntity.class,
|
||||||
.as(StepVerifier::create)
|
template.getIndexCoordinatesFor(OptimisticEntity.class))
|
||||||
.assertNext(this::assertThatSeqNoPrimaryTermIsFilled)
|
.map(SearchHit::getContent).as(StepVerifier::create).assertNext(this::assertThatSeqNoPrimaryTermIsFilled)
|
||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Query searchQueryForOne(String id) {
|
private Query searchQueryForOne(String id) {
|
||||||
return new NativeSearchQueryBuilder()
|
return new NativeSearchQueryBuilder().withFilter(new IdsQueryBuilder().addIds(id)).build();
|
||||||
.withFilter(new IdsQueryBuilder().addIds(id))
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-799
|
@Test // DATAES-799
|
||||||
@ -921,10 +926,7 @@ public class ReactiveElasticsearchTemplateTests {
|
|||||||
template.save(forEdit1).block();
|
template.save(forEdit1).block();
|
||||||
|
|
||||||
forEdit2.setMessage("It'll be great");
|
forEdit2.setMessage("It'll be great");
|
||||||
template.save(forEdit2)
|
template.save(forEdit2).as(StepVerifier::create).expectError(OptimisticLockingFailureException.class).verify();
|
||||||
.as(StepVerifier::create)
|
|
||||||
.expectError(OptimisticLockingFailureException.class)
|
|
||||||
.verify();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-799
|
@Test // DATAES-799
|
||||||
@ -940,10 +942,7 @@ public class ReactiveElasticsearchTemplateTests {
|
|||||||
template.save(forEdit1).block();
|
template.save(forEdit1).block();
|
||||||
|
|
||||||
forEdit2.setMessage("It'll be great");
|
forEdit2.setMessage("It'll be great");
|
||||||
template.save(forEdit2)
|
template.save(forEdit2).as(StepVerifier::create).expectError(OptimisticLockingFailureException.class).verify();
|
||||||
.as(StepVerifier::create)
|
|
||||||
.expectError(OptimisticLockingFailureException.class)
|
|
||||||
.verify();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-799
|
@Test // DATAES-799
|
||||||
@ -955,10 +954,7 @@ public class ReactiveElasticsearchTemplateTests {
|
|||||||
OptimisticAndVersionedEntity forEdit = template.get(saved.getId(), OptimisticAndVersionedEntity.class).block();
|
OptimisticAndVersionedEntity forEdit = template.get(saved.getId(), OptimisticAndVersionedEntity.class).block();
|
||||||
|
|
||||||
forEdit.setMessage("It'll be ok");
|
forEdit.setMessage("It'll be ok");
|
||||||
template.save(forEdit)
|
template.save(forEdit).as(StepVerifier::create).expectNextCount(1).verifyComplete();
|
||||||
.as(StepVerifier::create)
|
|
||||||
.expectNextCount(1)
|
|
||||||
.verifyComplete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@ -233,8 +233,8 @@ class RequestFactoryTests {
|
|||||||
when(client.prepareSearch(any())).thenReturn(new SearchRequestBuilder(client, SearchAction.INSTANCE));
|
when(client.prepareSearch(any())).thenReturn(new SearchRequestBuilder(client, SearchAction.INSTANCE));
|
||||||
Query query = new NativeSearchQueryBuilder().build();
|
Query query = new NativeSearchQueryBuilder().build();
|
||||||
|
|
||||||
SearchRequestBuilder builder = requestFactory.searchRequestBuilder(client, query,
|
SearchRequestBuilder builder = requestFactory.searchRequestBuilder(client, query, EntityWithSeqNoPrimaryTerm.class,
|
||||||
EntityWithSeqNoPrimaryTerm.class, IndexCoordinates.of("seqNoPrimaryTerm"));
|
IndexCoordinates.of("seqNoPrimaryTerm"));
|
||||||
|
|
||||||
assertThat(builder.request().source().seqNoAndPrimaryTerm()).isTrue();
|
assertThat(builder.request().source().seqNoAndPrimaryTerm()).isTrue();
|
||||||
}
|
}
|
||||||
|
@ -926,7 +926,8 @@ public class MappingElasticsearchConverterUnitTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@org.springframework.data.elasticsearch.annotations.Document(indexName = "test-index-entity-with-seq-no-primary-term-mapper")
|
@org.springframework.data.elasticsearch.annotations.Document(
|
||||||
|
indexName = "test-index-entity-with-seq-no-primary-term-mapper")
|
||||||
static class EntityWithSeqNoPrimaryTerm {
|
static class EntityWithSeqNoPrimaryTerm {
|
||||||
|
|
||||||
@Nullable private SeqNoPrimaryTerm seqNoPrimaryTerm;
|
@Nullable private SeqNoPrimaryTerm seqNoPrimaryTerm;
|
||||||
|
@ -99,7 +99,8 @@ public class SimpleElasticsearchPersistentEntityTests {
|
|||||||
|
|
||||||
@Test // DATAES-799
|
@Test // DATAES-799
|
||||||
void shouldReportThatThereIsNoSeqNoPrimaryTermPropertyWhenThereIsNoSuchProperty() {
|
void shouldReportThatThereIsNoSeqNoPrimaryTermPropertyWhenThereIsNoSuchProperty() {
|
||||||
TypeInformation<EntityWithoutSeqNoPrimaryTerm> typeInformation = ClassTypeInformation.from(EntityWithoutSeqNoPrimaryTerm.class);
|
TypeInformation<EntityWithoutSeqNoPrimaryTerm> typeInformation = ClassTypeInformation
|
||||||
|
.from(EntityWithoutSeqNoPrimaryTerm.class);
|
||||||
SimpleElasticsearchPersistentEntity<EntityWithoutSeqNoPrimaryTerm> entity = new SimpleElasticsearchPersistentEntity<>(
|
SimpleElasticsearchPersistentEntity<EntityWithoutSeqNoPrimaryTerm> entity = new SimpleElasticsearchPersistentEntity<>(
|
||||||
typeInformation);
|
typeInformation);
|
||||||
|
|
||||||
@ -108,7 +109,8 @@ public class SimpleElasticsearchPersistentEntityTests {
|
|||||||
|
|
||||||
@Test // DATAES-799
|
@Test // DATAES-799
|
||||||
void shouldReportThatThereIsSeqNoPrimaryTermPropertyWhenThereIsSuchProperty() {
|
void shouldReportThatThereIsSeqNoPrimaryTermPropertyWhenThereIsSuchProperty() {
|
||||||
TypeInformation<EntityWithSeqNoPrimaryTerm> typeInformation = ClassTypeInformation.from(EntityWithSeqNoPrimaryTerm.class);
|
TypeInformation<EntityWithSeqNoPrimaryTerm> typeInformation = ClassTypeInformation
|
||||||
|
.from(EntityWithSeqNoPrimaryTerm.class);
|
||||||
SimpleElasticsearchPersistentEntity<EntityWithSeqNoPrimaryTerm> entity = new SimpleElasticsearchPersistentEntity<>(
|
SimpleElasticsearchPersistentEntity<EntityWithSeqNoPrimaryTerm> entity = new SimpleElasticsearchPersistentEntity<>(
|
||||||
typeInformation);
|
typeInformation);
|
||||||
|
|
||||||
@ -119,7 +121,8 @@ public class SimpleElasticsearchPersistentEntityTests {
|
|||||||
|
|
||||||
@Test // DATAES-799
|
@Test // DATAES-799
|
||||||
void shouldReturnSeqNoPrimaryTermPropertyWhenThereIsSuchProperty() {
|
void shouldReturnSeqNoPrimaryTermPropertyWhenThereIsSuchProperty() {
|
||||||
TypeInformation<EntityWithSeqNoPrimaryTerm> typeInformation = ClassTypeInformation.from(EntityWithSeqNoPrimaryTerm.class);
|
TypeInformation<EntityWithSeqNoPrimaryTerm> typeInformation = ClassTypeInformation
|
||||||
|
.from(EntityWithSeqNoPrimaryTerm.class);
|
||||||
SimpleElasticsearchPersistentEntity<EntityWithSeqNoPrimaryTerm> entity = new SimpleElasticsearchPersistentEntity<>(
|
SimpleElasticsearchPersistentEntity<EntityWithSeqNoPrimaryTerm> entity = new SimpleElasticsearchPersistentEntity<>(
|
||||||
typeInformation);
|
typeInformation);
|
||||||
entity.addPersistentProperty(createProperty(entity, "seqNoPrimaryTerm"));
|
entity.addPersistentProperty(createProperty(entity, "seqNoPrimaryTerm"));
|
||||||
@ -134,7 +137,8 @@ public class SimpleElasticsearchPersistentEntityTests {
|
|||||||
|
|
||||||
@Test // DATAES-799
|
@Test // DATAES-799
|
||||||
void shouldNotAllowMoreThanOneSeqNoPrimaryTermProperties() {
|
void shouldNotAllowMoreThanOneSeqNoPrimaryTermProperties() {
|
||||||
TypeInformation<EntityWithSeqNoPrimaryTerm> typeInformation = ClassTypeInformation.from(EntityWithSeqNoPrimaryTerm.class);
|
TypeInformation<EntityWithSeqNoPrimaryTerm> typeInformation = ClassTypeInformation
|
||||||
|
.from(EntityWithSeqNoPrimaryTerm.class);
|
||||||
SimpleElasticsearchPersistentEntity<EntityWithSeqNoPrimaryTerm> entity = new SimpleElasticsearchPersistentEntity<>(
|
SimpleElasticsearchPersistentEntity<EntityWithSeqNoPrimaryTerm> entity = new SimpleElasticsearchPersistentEntity<>(
|
||||||
typeInformation);
|
typeInformation);
|
||||||
entity.addPersistentProperty(createProperty(entity, "seqNoPrimaryTerm"));
|
entity.addPersistentProperty(createProperty(entity, "seqNoPrimaryTerm"));
|
||||||
@ -202,8 +206,7 @@ public class SimpleElasticsearchPersistentEntityTests {
|
|||||||
@Nullable @Field(name = "renamed-field") private String renamedField;
|
@Nullable @Field(name = "renamed-field") private String renamedField;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class EntityWithoutSeqNoPrimaryTerm {
|
private static class EntityWithoutSeqNoPrimaryTerm {}
|
||||||
}
|
|
||||||
|
|
||||||
private static class EntityWithSeqNoPrimaryTerm {
|
private static class EntityWithSeqNoPrimaryTerm {
|
||||||
private SeqNoPrimaryTerm seqNoPrimaryTerm;
|
private SeqNoPrimaryTerm seqNoPrimaryTerm;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user