Update document partially by specified entity.

Original Pull Request #2310 
Closes #2304
This commit is contained in:
puppylpg 2022-09-26 03:19:14 +08:00 committed by GitHub
parent 1396f53fde
commit b038bbe778
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 76 additions and 2 deletions

View File

@ -8,4 +8,4 @@ In order to run the tests locally with `./mvnw test` you need to have docker run
== Class names of the test classes
Tset classes that do depend on the client have either `ERHLC` (when using the deprecated Elasticsearch `RestHighLevelClient`) or `ELC` (the new `ElasticsearchClient`) in their name.
Test classes that do depend on the client have either `ERHLC` (when using the deprecated Elasticsearch `RestHighLevelClient`) or `ELC` (the new `ElasticsearchClient`) in their name.

View File

@ -49,6 +49,7 @@ import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.data.elasticsearch.core.query.UpdateResponse;
import org.springframework.data.elasticsearch.core.routing.DefaultRoutingResolver;
import org.springframework.data.elasticsearch.core.routing.RoutingResolver;
import org.springframework.data.elasticsearch.support.VersionInfo;
@ -75,6 +76,7 @@ import org.springframework.util.Assert;
* @author Subhobrata Dey
* @author Steven Pearce
* @author Anton Naydenov
* @author Haibo Liu
*/
public abstract class AbstractElasticsearchTemplate implements ElasticsearchOperations, ApplicationContextAware {
@ -305,7 +307,7 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
@Override
public String delete(Object entity, IndexCoordinates index) {
String entityId = getEntityId(entity);
Assert.notNull(entityId, "entity must have an if that is notnull");
Assert.notNull(entityId, "entity must have an id that is notnull");
return this.delete(entityId, index);
}
@ -460,6 +462,27 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
return getRequiredPersistentEntity(clazz).getIndexCoordinates();
}
@Override
public <T> UpdateResponse update(T entity) {
return update(buildUpdateQueryByEntity(entity), getIndexCoordinatesFor(entity.getClass()));
}
protected <T> UpdateQuery buildUpdateQueryByEntity(T entity) {
Assert.notNull(entity, "entity must not be null");
String id = getEntityId(entity);
Assert.notNull(entity, "entity must have an id that is notnull");
UpdateQuery.Builder updateQueryBuilder = UpdateQuery.builder(id)
.withDocument(elasticsearchConverter.mapObject(entity));
String routing = getEntityRouting(entity);
if (Objects.nonNull(routing)) {
updateQueryBuilder.withRouting(routing);
}
return updateQueryBuilder.build();
}
protected <T> T updateIndexedObject(T entity, IndexedObjectInformation indexedObjectInformation) {
ElasticsearchPersistentEntity<?> persistentEntity = elasticsearchConverter.getMappingContext()

View File

@ -37,6 +37,7 @@ import org.springframework.lang.Nullable;
* @author Peter-Josef Meisch
* @author Farid Faoudi
* @author Sijia Liu
* @author Haibo Liu
* @since 4.0
*/
public interface DocumentOperations {
@ -293,6 +294,15 @@ public interface DocumentOperations {
*/
ByQueryResponse delete(Query query, Class<?> clazz, IndexCoordinates index);
/**
* Partially update a document by the given entity.
*
* @param entity the entity to update partially
* @return the update response
* @param <T> the entity type
*/
<T> UpdateResponse update(T entity);
/**
* Partial update of the document.
*

View File

@ -112,6 +112,7 @@ import org.springframework.lang.Nullable;
* @author Farid Faoudi
* @author Peer Mueller
* @author Sijia Liu
* @author Haibo Liu
*/
@SpringIntegrationTest
public abstract class ElasticsearchIntegrationTests {
@ -186,6 +187,20 @@ public abstract class ElasticsearchIntegrationTests {
protected abstract Query getQueryWithRescorer();
@Test // #2304
public void shouldThrowDataAccessExceptionIfDocumentDoesNotExistWhileDoingPartialUpdateByEntity() {
// given
String documentId = nextIdAsString();
String messageBeforeUpdate = "some test message";
SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message(messageBeforeUpdate)
.version(System.currentTimeMillis()).build();
assertThatThrownBy(() -> operations.update(sampleEntity))
.isInstanceOf(DataAccessException.class);
}
@Test
public void shouldThrowDataAccessExceptionIfDocumentDoesNotExistWhileDoingPartialUpdate() {
@ -1505,6 +1520,32 @@ public abstract class ElasticsearchIntegrationTests {
assertThat(indexOperations.exists()).isFalse();
}
@Test // #2304
public void shouldDoPartialUpdateBySuppliedEntityForExistingDocument() {
// given
String documentId = nextIdAsString();
String messageBeforeUpdate = "some test message";
String messageAfterUpdate = "test message";
String originalTypeInfo = "some type";
SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message(messageBeforeUpdate).type(originalTypeInfo)
.version(System.currentTimeMillis()).build();
operations.save(sampleEntity);
// modify the entity
sampleEntity.setMessage(messageAfterUpdate);
sampleEntity.setType(null);
// when
operations.update(sampleEntity);
// then
SampleEntity indexedEntity = operations.get(documentId, SampleEntity.class);
assertThat(indexedEntity.getType()).isEqualTo(originalTypeInfo);
assertThat(indexedEntity.getMessage()).isEqualTo(messageAfterUpdate);
}
@Test
public void shouldDoPartialUpdateForExistingDocument() {