mirror of
				https://github.com/spring-projects/spring-data-elasticsearch.git
				synced 2025-10-30 22:28:47 +00:00 
			
		
		
		
	DATAES-198 - Fixed @Version annotation on fields.
This commit is contained in:
		
							parent
							
								
									de1afe8bb0
								
							
						
					
					
						commit
						ef1dca31e4
					
				| @ -39,6 +39,7 @@ import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPa | |||||||
| import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; | import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; | ||||||
| import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; | import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; | ||||||
| import org.springframework.data.mapping.context.MappingContext; | import org.springframework.data.mapping.context.MappingContext; | ||||||
|  | import org.springframework.util.Assert; | ||||||
| 
 | 
 | ||||||
| import com.fasterxml.jackson.core.JsonEncoding; | import com.fasterxml.jackson.core.JsonEncoding; | ||||||
| import com.fasterxml.jackson.core.JsonFactory; | import com.fasterxml.jackson.core.JsonFactory; | ||||||
| @ -49,6 +50,7 @@ import com.fasterxml.jackson.core.JsonGenerator; | |||||||
|  * @author Petar Tahchiev |  * @author Petar Tahchiev | ||||||
|  * @author Young Gu |  * @author Young Gu | ||||||
|  * @author Oliver Gierke |  * @author Oliver Gierke | ||||||
|  |  * @author Chris White | ||||||
|  * @author Mark Paluch |  * @author Mark Paluch | ||||||
|  * @author Ilkang Na |  * @author Ilkang Na | ||||||
|  */ |  */ | ||||||
| @ -89,6 +91,7 @@ public class DefaultResultMapper extends AbstractResultMapper { | |||||||
| 					result = mapEntity(hit.getFields().values(), clazz); | 					result = mapEntity(hit.getFields().values(), clazz); | ||||||
| 				} | 				} | ||||||
| 				setPersistentEntityId(result, hit.getId(), clazz); | 				setPersistentEntityId(result, hit.getId(), clazz); | ||||||
|  | 				setPersistentEntityVersion(result, hit.getVersion(), clazz); | ||||||
| 				populateScriptFields(result, hit); | 				populateScriptFields(result, hit); | ||||||
| 				results.add(result); | 				results.add(result); | ||||||
| 			} | 			} | ||||||
| @ -154,6 +157,7 @@ public class DefaultResultMapper extends AbstractResultMapper { | |||||||
| 		T result = mapEntity(response.getSourceAsString(), clazz); | 		T result = mapEntity(response.getSourceAsString(), clazz); | ||||||
| 		if (result != null) { | 		if (result != null) { | ||||||
| 			setPersistentEntityId(result, response.getId(), clazz); | 			setPersistentEntityId(result, response.getId(), clazz); | ||||||
|  | 			setPersistentEntityVersion(result, response.getVersion(), clazz); | ||||||
| 		} | 		} | ||||||
| 		return result; | 		return result; | ||||||
| 	} | 	} | ||||||
| @ -165,6 +169,7 @@ public class DefaultResultMapper extends AbstractResultMapper { | |||||||
| 			if (!response.isFailed() && response.getResponse().isExists()) { | 			if (!response.isFailed() && response.getResponse().isExists()) { | ||||||
| 				T result = mapEntity(response.getResponse().getSourceAsString(), clazz); | 				T result = mapEntity(response.getResponse().getSourceAsString(), clazz); | ||||||
| 				setPersistentEntityId(result, response.getResponse().getId(), clazz); | 				setPersistentEntityId(result, response.getResponse().getId(), clazz); | ||||||
|  | 				setPersistentEntityVersion(result, response.getResponse().getVersion(), clazz); | ||||||
| 				list.add(result); | 				list.add(result); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @ -185,4 +190,20 @@ public class DefaultResultMapper extends AbstractResultMapper { | |||||||
| 
 | 
 | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	private <T> void setPersistentEntityVersion(T result, long version, Class<T> clazz) { | ||||||
|  | 		if (mappingContext != null && clazz.isAnnotationPresent(Document.class)) { | ||||||
|  | 
 | ||||||
|  | 			ElasticsearchPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(clazz); | ||||||
|  | 			ElasticsearchPersistentProperty versionProperty = persistentEntity.getVersionProperty(); | ||||||
|  | 
 | ||||||
|  | 			// Only deal with Long because ES versions are longs ! | ||||||
|  | 			if (versionProperty != null && versionProperty.getType().isAssignableFrom(Long.class)) { | ||||||
|  | 				// check that a version was actually returned in the response, -1 would indicate that | ||||||
|  | 				// a search didn't request the version ids in the response, which would be an issue | ||||||
|  | 				Assert.isTrue(version != -1, "Version in response is -1"); | ||||||
|  | 				persistentEntity.getPropertyAccessor(result).setProperty(versionProperty, version); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -106,6 +106,7 @@ import org.springframework.util.Assert; | |||||||
|  * @author Young Gu |  * @author Young Gu | ||||||
|  * @author Oliver Gierke |  * @author Oliver Gierke | ||||||
|  * @author Mark Janssen |  * @author Mark Janssen | ||||||
|  |  * @author Chris White | ||||||
|  * @author Mark Paluch |  * @author Mark Paluch | ||||||
|  * @author Ilkang Na |  * @author Ilkang Na | ||||||
|  * @author Alen Turkovic |  * @author Alen Turkovic | ||||||
| @ -733,7 +734,10 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati | |||||||
| 
 | 
 | ||||||
| 	private SearchRequestBuilder prepareScroll(Query query, long scrollTimeInMillis) { | 	private SearchRequestBuilder prepareScroll(Query query, long scrollTimeInMillis) { | ||||||
| 		SearchRequestBuilder requestBuilder = client.prepareSearch(toArray(query.getIndices())) | 		SearchRequestBuilder requestBuilder = client.prepareSearch(toArray(query.getIndices())) | ||||||
| 				.setTypes(toArray(query.getTypes())).setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)).setFrom(0); | 				.setTypes(toArray(query.getTypes())) | ||||||
|  | 				.setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)) | ||||||
|  | 				.setFrom(0) | ||||||
|  | 				.setVersion(true); | ||||||
| 
 | 
 | ||||||
| 		if(query.getPageable().isPaged()){ | 		if(query.getPageable().isPaged()){ | ||||||
| 			requestBuilder.setSize(query.getPageable().getPageSize()); | 			requestBuilder.setSize(query.getPageable().getPageSize()); | ||||||
| @ -979,7 +983,9 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati | |||||||
| 
 | 
 | ||||||
| 		int startRecord = 0; | 		int startRecord = 0; | ||||||
| 		SearchRequestBuilder searchRequestBuilder = client.prepareSearch(toArray(query.getIndices())) | 		SearchRequestBuilder searchRequestBuilder = client.prepareSearch(toArray(query.getIndices())) | ||||||
| 				.setSearchType(query.getSearchType()).setTypes(toArray(query.getTypes())); | 				.setSearchType(query.getSearchType()) | ||||||
|  | 				.setTypes(toArray(query.getTypes())) | ||||||
|  | 				.setVersion(true); | ||||||
| 
 | 
 | ||||||
| 		if (query.getSourceFilter() != null) { | 		if (query.getSourceFilter() != null) { | ||||||
| 			SourceFilter sourceFilter = query.getSourceFilter(); | 			SourceFilter sourceFilter = query.getSourceFilter(); | ||||||
|  | |||||||
| @ -15,13 +15,17 @@ | |||||||
|  */ |  */ | ||||||
| package org.springframework.data.elasticsearch.core; | package org.springframework.data.elasticsearch.core; | ||||||
| 
 | 
 | ||||||
|  | import java.util.Arrays; | ||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
|  | import java.util.LinkedList; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| 
 | 
 | ||||||
| import com.fasterxml.jackson.databind.util.ArrayIterator; | import com.fasterxml.jackson.databind.util.ArrayIterator; | ||||||
| import lombok.Getter; | import lombok.Getter; | ||||||
| import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||||
| import org.elasticsearch.action.get.GetResponse; | import org.elasticsearch.action.get.GetResponse; | ||||||
|  | import org.elasticsearch.action.get.MultiGetItemResponse; | ||||||
|  | import org.elasticsearch.action.get.MultiGetResponse; | ||||||
| import org.elasticsearch.action.search.SearchResponse; | import org.elasticsearch.action.search.SearchResponse; | ||||||
| import org.elasticsearch.common.document.DocumentField; | import org.elasticsearch.common.document.DocumentField; | ||||||
| import org.elasticsearch.search.SearchHit; | import org.elasticsearch.search.SearchHit; | ||||||
| @ -39,6 +43,7 @@ import org.springframework.data.elasticsearch.annotations.Document; | |||||||
| import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; | import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; | ||||||
| import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; | import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; | ||||||
| import org.springframework.data.elasticsearch.entities.Car; | import org.springframework.data.elasticsearch.entities.Car; | ||||||
|  | import org.springframework.data.elasticsearch.entities.SampleEntity; | ||||||
| 
 | 
 | ||||||
| import static java.util.Arrays.asList; | import static java.util.Arrays.asList; | ||||||
| import static org.hamcrest.Matchers.*; | import static org.hamcrest.Matchers.*; | ||||||
| @ -48,6 +53,7 @@ import static org.mockito.Mockito.*; | |||||||
| /** | /** | ||||||
|  * @author Artur Konczak |  * @author Artur Konczak | ||||||
|  * @author Mohsin Husen |  * @author Mohsin Husen | ||||||
|  |  * @author Chris White | ||||||
|  * @author Mark Paluch |  * @author Mark Paluch | ||||||
|  * @author Ilkang Na |  * @author Ilkang Na | ||||||
|  */ |  */ | ||||||
| @ -152,6 +158,69 @@ public class DefaultResultMapperTests { | |||||||
| 		assertThat(result.getId(), is("identifier")); | 		assertThat(result.getId(), is("identifier")); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	@Test // DATAES-198 | ||||||
|  | 	public void setsVersionFromGetResponse() { | ||||||
|  | 		GetResponse response = mock(GetResponse.class); | ||||||
|  | 		when(response.getSourceAsString()).thenReturn("{}"); | ||||||
|  | 		when(response.getVersion()).thenReturn(1234L); | ||||||
|  | 
 | ||||||
|  | 		SampleEntity result = resultMapper.mapResult(response, SampleEntity.class); | ||||||
|  | 
 | ||||||
|  | 		assertThat(result, is(notNullValue())); | ||||||
|  | 		assertThat(result.getVersion(), is(1234L)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test // DATAES-198 | ||||||
|  | 	public void setsVersionFromMultiGetResponse() { | ||||||
|  | 		GetResponse response1 = mock(GetResponse.class); | ||||||
|  | 		when(response1.getSourceAsString()).thenReturn("{}"); | ||||||
|  | 		when(response1.isExists()).thenReturn(true); | ||||||
|  | 		when(response1.getVersion()).thenReturn(1234L); | ||||||
|  | 
 | ||||||
|  | 		GetResponse response2 = mock(GetResponse.class); | ||||||
|  | 		when(response2.getSourceAsString()).thenReturn("{}"); | ||||||
|  | 		when(response2.isExists()).thenReturn(true); | ||||||
|  | 		when(response2.getVersion()).thenReturn(5678L); | ||||||
|  | 
 | ||||||
|  | 		MultiGetResponse multiResponse = mock(MultiGetResponse.class); | ||||||
|  | 		when(multiResponse.getResponses()).thenReturn(new MultiGetItemResponse[] { | ||||||
|  | 				new MultiGetItemResponse(response1, null), new MultiGetItemResponse(response2, null) }); | ||||||
|  | 
 | ||||||
|  | 		LinkedList<SampleEntity> results = resultMapper.mapResults(multiResponse, SampleEntity.class); | ||||||
|  | 
 | ||||||
|  | 		assertThat(results, is(notNullValue())); | ||||||
|  | 		assertThat(results, hasSize(2)); | ||||||
|  | 
 | ||||||
|  | 		assertThat(results.get(0).getVersion(), is(1234L)); | ||||||
|  | 		assertThat(results.get(1).getVersion(), is(5678L)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test // DATAES-198 | ||||||
|  | 	public void setsVersionFromSearchResponse() { | ||||||
|  | 		SearchHit hit1 = mock(SearchHit.class); | ||||||
|  | 		when(hit1.getSourceAsString()).thenReturn("{}"); | ||||||
|  | 		when(hit1.getVersion()).thenReturn(1234L); | ||||||
|  | 
 | ||||||
|  | 		SearchHit hit2 = mock(SearchHit.class); | ||||||
|  | 		when(hit2.getSourceAsString()).thenReturn("{}"); | ||||||
|  | 		when(hit2.getVersion()).thenReturn(5678L); | ||||||
|  | 
 | ||||||
|  | 		SearchHits searchHits = mock(SearchHits.class); | ||||||
|  | 		when(searchHits.getTotalHits()).thenReturn(2L); | ||||||
|  | 		when(searchHits.iterator()).thenReturn(Arrays.asList(hit1, hit2).iterator()); | ||||||
|  | 
 | ||||||
|  | 		SearchResponse searchResponse = mock(SearchResponse.class); | ||||||
|  | 		when(searchResponse.getHits()).thenReturn(searchHits); | ||||||
|  | 
 | ||||||
|  | 		AggregatedPage<SampleEntity> results = resultMapper.mapResults(searchResponse, SampleEntity.class, | ||||||
|  | 				mock(Pageable.class)); | ||||||
|  | 
 | ||||||
|  | 		assertThat(results, is(notNullValue())); | ||||||
|  | 
 | ||||||
|  | 		assertThat(results.getContent().get(0).getVersion(), is(1234L)); | ||||||
|  | 		assertThat(results.getContent().get(1).getVersion(), is(5678L)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	private Aggregation createCarAggregation() { | 	private Aggregation createCarAggregation() { | ||||||
| 		Aggregation aggregation = mock(Terms.class); | 		Aggregation aggregation = mock(Terms.class); | ||||||
| 		when(aggregation.getName()).thenReturn("Diesel"); | 		when(aggregation.getName()).thenReturn("Diesel"); | ||||||
|  | |||||||
| @ -71,6 +71,7 @@ import static org.springframework.data.elasticsearch.utils.IndexBuilder.*; | |||||||
|  * @author Abdul Mohammed |  * @author Abdul Mohammed | ||||||
|  * @author Kevin Leturc |  * @author Kevin Leturc | ||||||
|  * @author Mason Chan |  * @author Mason Chan | ||||||
|  |  * @author Chris White | ||||||
|  * @author Ilkang Na |  * @author Ilkang Na | ||||||
|  * @author Alen Turkovic |  * @author Alen Turkovic | ||||||
|  */ |  */ | ||||||
| @ -2017,13 +2018,17 @@ public class ElasticsearchTemplateTests { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private IndexQuery getIndexQuery(SampleEntity sampleEntity) { | 	private IndexQuery getIndexQuery(SampleEntity sampleEntity) { | ||||||
| 		return new IndexQueryBuilder().withId(sampleEntity.getId()).withObject(sampleEntity).build(); | 		return new IndexQueryBuilder() | ||||||
|  | 				.withId(sampleEntity.getId()) | ||||||
|  | 				.withObject(sampleEntity) | ||||||
|  | 				.withVersion(sampleEntity.getVersion()) | ||||||
|  | 				.build(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private List<IndexQuery> getIndexQueries(List<SampleEntity> sampleEntities) { | 	private List<IndexQuery> getIndexQueries(List<SampleEntity> sampleEntities) { | ||||||
| 		List<IndexQuery> indexQueries = new ArrayList<>(); | 		List<IndexQuery> indexQueries = new ArrayList<>(); | ||||||
| 		for (SampleEntity sampleEntity : sampleEntities) { | 		for (SampleEntity sampleEntity : sampleEntities) { | ||||||
| 			indexQueries.add(new IndexQueryBuilder().withId(sampleEntity.getId()).withObject(sampleEntity).build()); | 			indexQueries.add(getIndexQuery(sampleEntity)); | ||||||
| 		} | 		} | ||||||
| 		return indexQueries; | 		return indexQueries; | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -23,6 +23,7 @@ import lombok.Builder; | |||||||
| import lombok.Getter; | import lombok.Getter; | ||||||
| import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||||
| import lombok.Setter; | import lombok.Setter; | ||||||
|  | import lombok.ToString; | ||||||
| import org.springframework.data.annotation.Id; | import org.springframework.data.annotation.Id; | ||||||
| import org.springframework.data.annotation.Version; | import org.springframework.data.annotation.Version; | ||||||
| import org.springframework.data.elasticsearch.annotations.Document; | import org.springframework.data.elasticsearch.annotations.Document; | ||||||
| @ -34,12 +35,14 @@ import static org.springframework.data.elasticsearch.annotations.FieldType.*; | |||||||
| /** | /** | ||||||
|  * @author Rizwan Idrees |  * @author Rizwan Idrees | ||||||
|  * @author Mohsin Husen |  * @author Mohsin Husen | ||||||
|  |  * @author Chris White | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @Setter | @Setter | ||||||
| @Getter | @Getter | ||||||
| @NoArgsConstructor | @NoArgsConstructor | ||||||
| @AllArgsConstructor | @AllArgsConstructor | ||||||
|  | @ToString | ||||||
| @Builder | @Builder | ||||||
| @Document(indexName = "test-index-sample", type = "test-type", shards = 1, replicas = 0, refreshInterval = "-1") | @Document(indexName = "test-index-sample", type = "test-type", shards = 1, replicas = 0, refreshInterval = "-1") | ||||||
| public class SampleEntity { | public class SampleEntity { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user