Skip to content

Commit ef1dca3

Browse files
chriswhite199xhaggi
authored andcommitted
DATAES-198 - Fixed @Version annotation on fields.
1 parent de1afe8 commit ef1dca3

File tree

5 files changed

+108
-4
lines changed

5 files changed

+108
-4
lines changed

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
4040
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
4141
import org.springframework.data.mapping.context.MappingContext;
42+
import org.springframework.util.Assert;
4243

4344
import com.fasterxml.jackson.core.JsonEncoding;
4445
import com.fasterxml.jackson.core.JsonFactory;
@@ -49,6 +50,7 @@
4950
* @author Petar Tahchiev
5051
* @author Young Gu
5152
* @author Oliver Gierke
53+
* @author Chris White
5254
* @author Mark Paluch
5355
* @author Ilkang Na
5456
*/
@@ -89,6 +91,7 @@ public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz,
8991
result = mapEntity(hit.getFields().values(), clazz);
9092
}
9193
setPersistentEntityId(result, hit.getId(), clazz);
94+
setPersistentEntityVersion(result, hit.getVersion(), clazz);
9295
populateScriptFields(result, hit);
9396
results.add(result);
9497
}
@@ -154,6 +157,7 @@ public <T> T mapResult(GetResponse response, Class<T> clazz) {
154157
T result = mapEntity(response.getSourceAsString(), clazz);
155158
if (result != null) {
156159
setPersistentEntityId(result, response.getId(), clazz);
160+
setPersistentEntityVersion(result, response.getVersion(), clazz);
157161
}
158162
return result;
159163
}
@@ -165,6 +169,7 @@ public <T> LinkedList<T> mapResults(MultiGetResponse responses, Class<T> clazz)
165169
if (!response.isFailed() && response.getResponse().isExists()) {
166170
T result = mapEntity(response.getResponse().getSourceAsString(), clazz);
167171
setPersistentEntityId(result, response.getResponse().getId(), clazz);
172+
setPersistentEntityVersion(result, response.getResponse().getVersion(), clazz);
168173
list.add(result);
169174
}
170175
}
@@ -185,4 +190,20 @@ private <T> void setPersistentEntityId(T result, String id, Class<T> clazz) {
185190

186191
}
187192
}
193+
194+
private <T> void setPersistentEntityVersion(T result, long version, Class<T> clazz) {
195+
if (mappingContext != null && clazz.isAnnotationPresent(Document.class)) {
196+
197+
ElasticsearchPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(clazz);
198+
ElasticsearchPersistentProperty versionProperty = persistentEntity.getVersionProperty();
199+
200+
// Only deal with Long because ES versions are longs !
201+
if (versionProperty != null && versionProperty.getType().isAssignableFrom(Long.class)) {
202+
// check that a version was actually returned in the response, -1 would indicate that
203+
// a search didn't request the version ids in the response, which would be an issue
204+
Assert.isTrue(version != -1, "Version in response is -1");
205+
persistentEntity.getPropertyAccessor(result).setProperty(versionProperty, version);
206+
}
207+
}
208+
}
188209
}

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
* @author Young Gu
107107
* @author Oliver Gierke
108108
* @author Mark Janssen
109+
* @author Chris White
109110
* @author Mark Paluch
110111
* @author Ilkang Na
111112
* @author Alen Turkovic
@@ -733,7 +734,10 @@ private <T> SearchRequestBuilder prepareScroll(Query query, long scrollTimeInMil
733734

734735
private SearchRequestBuilder prepareScroll(Query query, long scrollTimeInMillis) {
735736
SearchRequestBuilder requestBuilder = client.prepareSearch(toArray(query.getIndices()))
736-
.setTypes(toArray(query.getTypes())).setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)).setFrom(0);
737+
.setTypes(toArray(query.getTypes()))
738+
.setScroll(TimeValue.timeValueMillis(scrollTimeInMillis))
739+
.setFrom(0)
740+
.setVersion(true);
737741

738742
if(query.getPageable().isPaged()){
739743
requestBuilder.setSize(query.getPageable().getPageSize());
@@ -979,7 +983,9 @@ private SearchRequestBuilder prepareSearch(Query query) {
979983

980984
int startRecord = 0;
981985
SearchRequestBuilder searchRequestBuilder = client.prepareSearch(toArray(query.getIndices()))
982-
.setSearchType(query.getSearchType()).setTypes(toArray(query.getTypes()));
986+
.setSearchType(query.getSearchType())
987+
.setTypes(toArray(query.getTypes()))
988+
.setVersion(true);
983989

984990
if (query.getSourceFilter() != null) {
985991
SourceFilter sourceFilter = query.getSourceFilter();

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

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,17 @@
1515
*/
1616
package org.springframework.data.elasticsearch.core;
1717

18+
import java.util.Arrays;
1819
import java.util.HashMap;
20+
import java.util.LinkedList;
1921
import java.util.Map;
2022

2123
import com.fasterxml.jackson.databind.util.ArrayIterator;
2224
import lombok.Getter;
2325
import lombok.NoArgsConstructor;
2426
import org.elasticsearch.action.get.GetResponse;
27+
import org.elasticsearch.action.get.MultiGetItemResponse;
28+
import org.elasticsearch.action.get.MultiGetResponse;
2529
import org.elasticsearch.action.search.SearchResponse;
2630
import org.elasticsearch.common.document.DocumentField;
2731
import org.elasticsearch.search.SearchHit;
@@ -39,6 +43,7 @@
3943
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
4044
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
4145
import org.springframework.data.elasticsearch.entities.Car;
46+
import org.springframework.data.elasticsearch.entities.SampleEntity;
4247

4348
import static java.util.Arrays.asList;
4449
import static org.hamcrest.Matchers.*;
@@ -48,6 +53,7 @@
4853
/**
4954
* @author Artur Konczak
5055
* @author Mohsin Husen
56+
* @author Chris White
5157
* @author Mark Paluch
5258
* @author Ilkang Na
5359
*/
@@ -152,6 +158,69 @@ public void setsIdentifierOnImmutableType() {
152158
assertThat(result.getId(), is("identifier"));
153159
}
154160

161+
@Test // DATAES-198
162+
public void setsVersionFromGetResponse() {
163+
GetResponse response = mock(GetResponse.class);
164+
when(response.getSourceAsString()).thenReturn("{}");
165+
when(response.getVersion()).thenReturn(1234L);
166+
167+
SampleEntity result = resultMapper.mapResult(response, SampleEntity.class);
168+
169+
assertThat(result, is(notNullValue()));
170+
assertThat(result.getVersion(), is(1234L));
171+
}
172+
173+
@Test // DATAES-198
174+
public void setsVersionFromMultiGetResponse() {
175+
GetResponse response1 = mock(GetResponse.class);
176+
when(response1.getSourceAsString()).thenReturn("{}");
177+
when(response1.isExists()).thenReturn(true);
178+
when(response1.getVersion()).thenReturn(1234L);
179+
180+
GetResponse response2 = mock(GetResponse.class);
181+
when(response2.getSourceAsString()).thenReturn("{}");
182+
when(response2.isExists()).thenReturn(true);
183+
when(response2.getVersion()).thenReturn(5678L);
184+
185+
MultiGetResponse multiResponse = mock(MultiGetResponse.class);
186+
when(multiResponse.getResponses()).thenReturn(new MultiGetItemResponse[] {
187+
new MultiGetItemResponse(response1, null), new MultiGetItemResponse(response2, null) });
188+
189+
LinkedList<SampleEntity> results = resultMapper.mapResults(multiResponse, SampleEntity.class);
190+
191+
assertThat(results, is(notNullValue()));
192+
assertThat(results, hasSize(2));
193+
194+
assertThat(results.get(0).getVersion(), is(1234L));
195+
assertThat(results.get(1).getVersion(), is(5678L));
196+
}
197+
198+
@Test // DATAES-198
199+
public void setsVersionFromSearchResponse() {
200+
SearchHit hit1 = mock(SearchHit.class);
201+
when(hit1.getSourceAsString()).thenReturn("{}");
202+
when(hit1.getVersion()).thenReturn(1234L);
203+
204+
SearchHit hit2 = mock(SearchHit.class);
205+
when(hit2.getSourceAsString()).thenReturn("{}");
206+
when(hit2.getVersion()).thenReturn(5678L);
207+
208+
SearchHits searchHits = mock(SearchHits.class);
209+
when(searchHits.getTotalHits()).thenReturn(2L);
210+
when(searchHits.iterator()).thenReturn(Arrays.asList(hit1, hit2).iterator());
211+
212+
SearchResponse searchResponse = mock(SearchResponse.class);
213+
when(searchResponse.getHits()).thenReturn(searchHits);
214+
215+
AggregatedPage<SampleEntity> results = resultMapper.mapResults(searchResponse, SampleEntity.class,
216+
mock(Pageable.class));
217+
218+
assertThat(results, is(notNullValue()));
219+
220+
assertThat(results.getContent().get(0).getVersion(), is(1234L));
221+
assertThat(results.getContent().get(1).getVersion(), is(5678L));
222+
}
223+
155224
private Aggregation createCarAggregation() {
156225
Aggregation aggregation = mock(Terms.class);
157226
when(aggregation.getName()).thenReturn("Diesel");

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
* @author Abdul Mohammed
7272
* @author Kevin Leturc
7373
* @author Mason Chan
74+
* @author Chris White
7475
* @author Ilkang Na
7576
* @author Alen Turkovic
7677
*/
@@ -2017,13 +2018,17 @@ public void shouldReadFileFromClasspathRetainingNewlines() {
20172018
}
20182019

20192020
private IndexQuery getIndexQuery(SampleEntity sampleEntity) {
2020-
return new IndexQueryBuilder().withId(sampleEntity.getId()).withObject(sampleEntity).build();
2021+
return new IndexQueryBuilder()
2022+
.withId(sampleEntity.getId())
2023+
.withObject(sampleEntity)
2024+
.withVersion(sampleEntity.getVersion())
2025+
.build();
20212026
}
20222027

20232028
private List<IndexQuery> getIndexQueries(List<SampleEntity> sampleEntities) {
20242029
List<IndexQuery> indexQueries = new ArrayList<>();
20252030
for (SampleEntity sampleEntity : sampleEntities) {
2026-
indexQueries.add(new IndexQueryBuilder().withId(sampleEntity.getId()).withObject(sampleEntity).build());
2031+
indexQueries.add(getIndexQuery(sampleEntity));
20272032
}
20282033
return indexQueries;
20292034
}

src/test/java/org/springframework/data/elasticsearch/entities/SampleEntity.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import lombok.Getter;
2424
import lombok.NoArgsConstructor;
2525
import lombok.Setter;
26+
import lombok.ToString;
2627
import org.springframework.data.annotation.Id;
2728
import org.springframework.data.annotation.Version;
2829
import org.springframework.data.elasticsearch.annotations.Document;
@@ -34,12 +35,14 @@
3435
/**
3536
* @author Rizwan Idrees
3637
* @author Mohsin Husen
38+
* @author Chris White
3739
*/
3840

3941
@Setter
4042
@Getter
4143
@NoArgsConstructor
4244
@AllArgsConstructor
45+
@ToString
4346
@Builder
4447
@Document(indexName = "test-index-sample", type = "test-type", shards = 1, replicas = 0, refreshInterval = "-1")
4548
public class SampleEntity {

0 commit comments

Comments
 (0)