Skip to content

Commit b038bbe

Browse files
authored
Update document partially by specified entity.
Original Pull Request #2310 Closes #2304
1 parent 1396f53 commit b038bbe

File tree

4 files changed

+76
-2
lines changed

4 files changed

+76
-2
lines changed

CONTRIBUTING.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ In order to run the tests locally with `./mvnw test` you need to have docker run
88

99
== Class names of the test classes
1010

11-
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.
11+
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.

src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import org.springframework.data.elasticsearch.core.query.Query;
5050
import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm;
5151
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
52+
import org.springframework.data.elasticsearch.core.query.UpdateResponse;
5253
import org.springframework.data.elasticsearch.core.routing.DefaultRoutingResolver;
5354
import org.springframework.data.elasticsearch.core.routing.RoutingResolver;
5455
import org.springframework.data.elasticsearch.support.VersionInfo;
@@ -75,6 +76,7 @@
7576
* @author Subhobrata Dey
7677
* @author Steven Pearce
7778
* @author Anton Naydenov
79+
* @author Haibo Liu
7880
*/
7981
public abstract class AbstractElasticsearchTemplate implements ElasticsearchOperations, ApplicationContextAware {
8082

@@ -305,7 +307,7 @@ public String delete(Object entity) {
305307
@Override
306308
public String delete(Object entity, IndexCoordinates index) {
307309
String entityId = getEntityId(entity);
308-
Assert.notNull(entityId, "entity must have an if that is notnull");
310+
Assert.notNull(entityId, "entity must have an id that is notnull");
309311
return this.delete(entityId, index);
310312
}
311313

@@ -460,6 +462,27 @@ public IndexCoordinates getIndexCoordinatesFor(Class<?> clazz) {
460462
return getRequiredPersistentEntity(clazz).getIndexCoordinates();
461463
}
462464

465+
@Override
466+
public <T> UpdateResponse update(T entity) {
467+
return update(buildUpdateQueryByEntity(entity), getIndexCoordinatesFor(entity.getClass()));
468+
}
469+
470+
protected <T> UpdateQuery buildUpdateQueryByEntity(T entity) {
471+
Assert.notNull(entity, "entity must not be null");
472+
473+
String id = getEntityId(entity);
474+
Assert.notNull(entity, "entity must have an id that is notnull");
475+
476+
UpdateQuery.Builder updateQueryBuilder = UpdateQuery.builder(id)
477+
.withDocument(elasticsearchConverter.mapObject(entity));
478+
479+
String routing = getEntityRouting(entity);
480+
if (Objects.nonNull(routing)) {
481+
updateQueryBuilder.withRouting(routing);
482+
}
483+
return updateQueryBuilder.build();
484+
}
485+
463486
protected <T> T updateIndexedObject(T entity, IndexedObjectInformation indexedObjectInformation) {
464487

465488
ElasticsearchPersistentEntity<?> persistentEntity = elasticsearchConverter.getMappingContext()

src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
* @author Peter-Josef Meisch
3838
* @author Farid Faoudi
3939
* @author Sijia Liu
40+
* @author Haibo Liu
4041
* @since 4.0
4142
*/
4243
public interface DocumentOperations {
@@ -293,6 +294,15 @@ default void bulkUpdate(List<UpdateQuery> queries, IndexCoordinates index) {
293294
*/
294295
ByQueryResponse delete(Query query, Class<?> clazz, IndexCoordinates index);
295296

297+
/**
298+
* Partially update a document by the given entity.
299+
*
300+
* @param entity the entity to update partially
301+
* @return the update response
302+
* @param <T> the entity type
303+
*/
304+
<T> UpdateResponse update(T entity);
305+
296306
/**
297307
* Partial update of the document.
298308
*

src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchIntegrationTests.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@
112112
* @author Farid Faoudi
113113
* @author Peer Mueller
114114
* @author Sijia Liu
115+
* @author Haibo Liu
115116
*/
116117
@SpringIntegrationTest
117118
public abstract class ElasticsearchIntegrationTests {
@@ -186,6 +187,20 @@ protected abstract Query getMatchAllQueryWithIncludesAndInlineExpressionScript(@
186187

187188
protected abstract Query getQueryWithRescorer();
188189

190+
@Test // #2304
191+
public void shouldThrowDataAccessExceptionIfDocumentDoesNotExistWhileDoingPartialUpdateByEntity() {
192+
193+
// given
194+
String documentId = nextIdAsString();
195+
String messageBeforeUpdate = "some test message";
196+
197+
SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message(messageBeforeUpdate)
198+
.version(System.currentTimeMillis()).build();
199+
200+
assertThatThrownBy(() -> operations.update(sampleEntity))
201+
.isInstanceOf(DataAccessException.class);
202+
}
203+
189204
@Test
190205
public void shouldThrowDataAccessExceptionIfDocumentDoesNotExistWhileDoingPartialUpdate() {
191206

@@ -1505,6 +1520,32 @@ public void shouldDeleteIndexForGivenEntity() {
15051520
assertThat(indexOperations.exists()).isFalse();
15061521
}
15071522

1523+
@Test // #2304
1524+
public void shouldDoPartialUpdateBySuppliedEntityForExistingDocument() {
1525+
1526+
// given
1527+
String documentId = nextIdAsString();
1528+
String messageBeforeUpdate = "some test message";
1529+
String messageAfterUpdate = "test message";
1530+
String originalTypeInfo = "some type";
1531+
1532+
SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message(messageBeforeUpdate).type(originalTypeInfo)
1533+
.version(System.currentTimeMillis()).build();
1534+
operations.save(sampleEntity);
1535+
1536+
// modify the entity
1537+
sampleEntity.setMessage(messageAfterUpdate);
1538+
sampleEntity.setType(null);
1539+
1540+
// when
1541+
operations.update(sampleEntity);
1542+
1543+
// then
1544+
SampleEntity indexedEntity = operations.get(documentId, SampleEntity.class);
1545+
assertThat(indexedEntity.getType()).isEqualTo(originalTypeInfo);
1546+
assertThat(indexedEntity.getMessage()).isEqualTo(messageAfterUpdate);
1547+
}
1548+
15081549
@Test
15091550
public void shouldDoPartialUpdateForExistingDocument() {
15101551

0 commit comments

Comments
 (0)