diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultResultMapper.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultResultMapper.java index ff19a1d98..7eda3cdcb 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultResultMapper.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultResultMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,6 @@ */ package org.springframework.data.elasticsearch.core; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.Charset; @@ -23,10 +22,8 @@ import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; import java.util.List; +import java.util.Optional; -import com.fasterxml.jackson.core.JsonEncoding; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; import org.apache.commons.lang.StringUtils; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.get.MultiGetItemResponse; @@ -42,14 +39,18 @@ import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; -import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.context.MappingContext; +import com.fasterxml.jackson.core.JsonEncoding; +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerator; + /** * @author Artur Konczak * @author Petar Tahchiev * @author Young Gu * @author Oliver Gierke + * @author Mark Paluch */ public class DefaultResultMapper extends AbstractResultMapper { @@ -119,7 +120,6 @@ public class DefaultResultMapper extends AbstractResultMapper { } } - private T mapEntity(Collection values, Class clazz) { return mapEntity(buildJSONFromFields(values), clazz); } @@ -175,13 +175,17 @@ public class DefaultResultMapper extends AbstractResultMapper { if (mappingContext != null && clazz.isAnnotationPresent(Document.class)) { - ElasticsearchPersistentEntity persistentEntity = mappingContext.getPersistentEntity(clazz); - PersistentProperty idProperty = persistentEntity.getIdProperty(); - + ElasticsearchPersistentEntity persistentEntity = mappingContext.getRequiredPersistentEntity(clazz); + Optional idProperty = persistentEntity.getIdProperty(); + // Only deal with String because ES generated Ids are strings ! - if (idProperty != null && idProperty.getType().isAssignableFrom(String.class)) { - persistentEntity.getPropertyAccessor(result).setProperty(idProperty, id); - } + + idProperty.ifPresent(property -> { + if (property.getType().isAssignableFrom(String.class)) { + persistentEntity.getPropertyAccessor(result).setProperty(property, Optional.ofNullable(id)); + } + }); + } } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 87a994cbe..5492c6ead 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,8 +15,7 @@ */ package org.springframework.data.elasticsearch.core; -import static org.apache.commons.lang.StringUtils.isNotBlank; -import static org.apache.commons.lang.StringUtils.isBlank; +import static org.apache.commons.lang.StringUtils.*; import static org.elasticsearch.action.search.SearchType.*; import static org.elasticsearch.client.Requests.*; import static org.elasticsearch.cluster.metadata.AliasAction.Type.*; @@ -28,8 +27,14 @@ import static org.springframework.util.CollectionUtils.isEmpty; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; -import java.lang.reflect.Method; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Optional; import org.elasticsearch.action.ListenableActionFuture; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; @@ -76,7 +81,10 @@ import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.core.io.ClassPathResource; -import org.springframework.data.domain.*; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Mapping; @@ -87,9 +95,9 @@ import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverte import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; import org.springframework.data.elasticsearch.core.facet.FacetRequest; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; +import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; import org.springframework.data.elasticsearch.core.query.*; -import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.util.CloseableIterator; import org.springframework.util.Assert; @@ -104,8 +112,8 @@ import org.springframework.util.Assert; * @author Young Gu * @author Oliver Gierke * @author Mark Janssen + * @author Mark Paluch */ - public class ElasticsearchTemplate implements ElasticsearchOperations, ApplicationContextAware { private static final Logger logger = LoggerFactory.getLogger(ElasticsearchTemplate.class); @@ -122,8 +130,10 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati this(client, new MappingElasticsearchConverter(new SimpleElasticsearchMappingContext()), entityMapper); } - public ElasticsearchTemplate(Client client, ElasticsearchConverter elasticsearchConverter, EntityMapper entityMapper) { - this(client, elasticsearchConverter, new DefaultResultMapper(elasticsearchConverter.getMappingContext(), entityMapper)); + public ElasticsearchTemplate(Client client, ElasticsearchConverter elasticsearchConverter, + EntityMapper entityMapper) { + this(client, elasticsearchConverter, + new DefaultResultMapper(elasticsearchConverter.getMappingContext(), entityMapper)); } public ElasticsearchTemplate(Client client, ResultsMapper resultsMapper) { @@ -134,7 +144,8 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati this(client, elasticsearchConverter, new DefaultResultMapper(elasticsearchConverter.getMappingContext())); } - public ElasticsearchTemplate(Client client, ElasticsearchConverter elasticsearchConverter, ResultsMapper resultsMapper) { + public ElasticsearchTemplate(Client client, ElasticsearchConverter elasticsearchConverter, + ResultsMapper resultsMapper) { Assert.notNull(client, "Client must not be null!"); Assert.notNull(elasticsearchConverter, "ElasticsearchConverter must not be null!"); @@ -162,9 +173,7 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati @Override public boolean createIndex(String indexName) { Assert.notNull(indexName, "No index defined for Query"); - return client.admin().indices() - .create(Requests.createIndexRequest(indexName)) - .actionGet().isAcknowledged(); + return client.admin().indices().create(Requests.createIndexRequest(indexName)).actionGet().isAcknowledged(); } @Override @@ -183,8 +192,13 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(clazz); XContentBuilder xContentBuilder = null; try { - xContentBuilder = buildMapping(clazz, persistentEntity.getIndexType(), persistentEntity - .getIdProperty().getFieldName(), persistentEntity.getParentType()); + + Optional idProperty = persistentEntity.getIdProperty(); + + ElasticsearchPersistentProperty property = idProperty.orElseThrow(() -> new IllegalArgumentException(String.format("No Id property for %s found", clazz.getSimpleName()))); + + xContentBuilder = buildMapping(clazz, persistentEntity.getIndexType(), + property.getFieldName(), persistentEntity.getParentType().orElse(null)); } catch (Exception e) { throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e); } @@ -193,15 +207,15 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati @Override public boolean putMapping(Class clazz, Object mapping) { - return putMapping(getPersistentEntityFor(clazz).getIndexName(), getPersistentEntityFor(clazz).getIndexType(), mapping); + return putMapping(getPersistentEntityFor(clazz).getIndexName(), getPersistentEntityFor(clazz).getIndexType(), + mapping); } @Override public boolean putMapping(String indexName, String type, Object mapping) { Assert.notNull(indexName, "No index defined for putMapping()"); Assert.notNull(type, "No type defined for putMapping()"); - PutMappingRequestBuilder requestBuilder = client.admin().indices() - .preparePutMapping(indexName).setType(type); + PutMappingRequestBuilder requestBuilder = client.admin().indices().preparePutMapping(indexName).setType(type); if (mapping instanceof String) { requestBuilder.setSource(String.valueOf(mapping)); } else if (mapping instanceof Map) { @@ -221,7 +235,8 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati mappings = client.admin().indices().getMappings(new GetMappingsRequest().indices(indexName).types(type)) .actionGet().getMappings().get(indexName).get(type).getSourceAsMap(); } catch (Exception e) { - throw new ElasticsearchException("Error while getting mapping for indexName : " + indexName + " type : " + type + " " + e.getMessage()); + throw new ElasticsearchException( + "Error while getting mapping for indexName : " + indexName + " type : " + type + " " + e.getMessage()); } return mappings; } @@ -311,7 +326,8 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati @Override public Page queryForPage(CriteriaQuery criteriaQuery, Class clazz) { QueryBuilder elasticsearchQuery = new CriteriaQueryProcessor().createQueryFromCriteria(criteriaQuery.getCriteria()); - QueryBuilder elasticsearchFilter = new CriteriaFilterProcessor().createFilterFromCriteria(criteriaQuery.getCriteria()); + QueryBuilder elasticsearchFilter = new CriteriaFilterProcessor() + .createFilterFromCriteria(criteriaQuery.getCriteria()); SearchRequestBuilder searchRequestBuilder = prepareSearch(criteriaQuery, clazz); if (elasticsearchQuery != null) { @@ -330,8 +346,7 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati logger.debug("doSearch query:\n" + searchRequestBuilder.toString()); } - SearchResponse response = getSearchResponse(searchRequestBuilder - .execute()); + SearchResponse response = getSearchResponse(searchRequestBuilder.execute()); return resultsMapper.mapResults(response, clazz, criteriaQuery.getPageable()); } @@ -365,7 +380,8 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati return doStream(initScrollId, scrollTimeInMillis, clazz, mapper); } - private CloseableIterator doStream(final String initScrollId, final long scrollTimeInMillis, final Class clazz, final SearchResultMapper mapper) { + private CloseableIterator doStream(final String initScrollId, final long scrollTimeInMillis, + final Class clazz, final SearchResultMapper mapper) { return new CloseableIterator() { /** As we couldn't retrieve single result with scroll, store current hits. */ @@ -399,10 +415,10 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati // Test if it remains hits if (currentHits == null || !currentHits.hasNext()) { // Do a new request - SearchResponse response = getSearchResponse(client.prepareSearchScroll(scrollId) - .setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)).execute()); + SearchResponse response = getSearchResponse( + client.prepareSearchScroll(scrollId).setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)).execute()); // Save hits and scroll id - currentHits = mapper.mapResults(response, clazz, null).iterator(); + currentHits = mapper.mapResults(response, clazz, Pageable.NONE).iterator(); finished = !currentHits.hasNext(); scrollId = response.getScrollId(); } @@ -427,7 +443,8 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati @Override public long count(CriteriaQuery criteriaQuery, Class clazz) { QueryBuilder elasticsearchQuery = new CriteriaQueryProcessor().createQueryFromCriteria(criteriaQuery.getCriteria()); - QueryBuilder elasticsearchFilter = new CriteriaFilterProcessor().createFilterFromCriteria(criteriaQuery.getCriteria()); + QueryBuilder elasticsearchFilter = new CriteriaFilterProcessor() + .createFilterFromCriteria(criteriaQuery.getCriteria()); if (elasticsearchFilter == null) { return doCount(prepareCount(criteriaQuery, clazz), elasticsearchQuery); @@ -467,7 +484,8 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati return countRequestBuilder.execute().actionGet().getCount(); } - private long doCount(SearchRequestBuilder searchRequestBuilder, QueryBuilder elasticsearchQuery, QueryBuilder elasticsearchFilter) { + private long doCount(SearchRequestBuilder searchRequestBuilder, QueryBuilder elasticsearchQuery, + QueryBuilder elasticsearchFilter) { if (elasticsearchQuery != null) { searchRequestBuilder.setQuery(elasticsearchQuery); } else { @@ -481,8 +499,11 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati } private CountRequestBuilder prepareCount(Query query, Class clazz) { - String indexName[] = !isEmpty(query.getIndices()) ? query.getIndices().toArray(new String[query.getIndices().size()]) : retrieveIndexNameFromPersistentEntity(clazz); - String types[] = !isEmpty(query.getTypes()) ? query.getTypes().toArray(new String[query.getTypes().size()]) : retrieveTypeFromPersistentEntity(clazz); + String indexName[] = !isEmpty(query.getIndices()) + ? query.getIndices().toArray(new String[query.getIndices().size()]) + : retrieveIndexNameFromPersistentEntity(clazz); + String types[] = !isEmpty(query.getTypes()) ? query.getTypes().toArray(new String[query.getTypes().size()]) + : retrieveTypeFromPersistentEntity(clazz); Assert.notNull(indexName, "No index defined for Query"); @@ -501,8 +522,10 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati private MultiGetResponse getMultiResponse(Query searchQuery, Class clazz) { - String indexName = !isEmpty(searchQuery.getIndices()) ? searchQuery.getIndices().get(0) : getPersistentEntityFor(clazz).getIndexName(); - String type = !isEmpty(searchQuery.getTypes()) ? searchQuery.getTypes().get(0) : getPersistentEntityFor(clazz).getIndexType(); + String indexName = !isEmpty(searchQuery.getIndices()) ? searchQuery.getIndices().get(0) + : getPersistentEntityFor(clazz).getIndexName(); + String type = !isEmpty(searchQuery.getTypes()) ? searchQuery.getTypes().get(0) + : getPersistentEntityFor(clazz).getIndexType(); Assert.notNull(indexName, "No index defined for Query"); Assert.notNull(type, "No type define for Query"); @@ -547,8 +570,10 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati } private UpdateRequestBuilder prepareUpdate(UpdateQuery query) { - String indexName = isNotBlank(query.getIndexName()) ? query.getIndexName() : getPersistentEntityFor(query.getClazz()).getIndexName(); - String type = isNotBlank(query.getType()) ? query.getType() : getPersistentEntityFor(query.getClazz()).getIndexType(); + String indexName = isNotBlank(query.getIndexName()) ? query.getIndexName() + : getPersistentEntityFor(query.getClazz()).getIndexName(); + String type = isNotBlank(query.getType()) ? query.getType() + : getPersistentEntityFor(query.getClazz()).getIndexType(); Assert.notNull(indexName, "No index defined for Query"); Assert.notNull(type, "No type define for Query"); Assert.notNull(query.getId(), "No Id define for Query"); @@ -559,8 +584,7 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati if (query.getUpdateRequest().script() == null) { // doc if (query.DoUpsert()) { - updateRequestBuilder.setDocAsUpsert(true) - .setDoc(query.getUpdateRequest().doc()); + updateRequestBuilder.setDocAsUpsert(true).setDoc(query.getUpdateRequest().doc()); } else { updateRequestBuilder.setDoc(query.getUpdateRequest().doc()); } @@ -587,8 +611,8 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati } throw new ElasticsearchException( "Bulk indexing has failures. Use ElasticsearchException.getFailedDocuments() for detailed messages [" - + failedDocuments + "]", failedDocuments - ); + + failedDocuments + "]", + failedDocuments); } } @@ -607,8 +631,8 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati } throw new ElasticsearchException( "Bulk indexing has failures. Use ElasticsearchException.getFailedDocuments() for detailed messages [" - + failedDocuments + "]", failedDocuments - ); + + failedDocuments + "]", + failedDocuments); } } @@ -624,8 +648,8 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati @Override public boolean typeExists(String index, String type) { - return client.admin().cluster().prepareState().execute().actionGet() - .getState().metaData().index(index).getMappings().containsKey(type); + return client.admin().cluster().prepareState().execute().actionGet().getState().metaData().index(index) + .getMappings().containsKey(type); } @Override @@ -656,16 +680,16 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati @Override public void delete(DeleteQuery deleteQuery, Class clazz) { - String indexName = isNotBlank(deleteQuery.getIndex()) ? deleteQuery.getIndex() : getPersistentEntityFor(clazz).getIndexName(); - String typeName = isNotBlank(deleteQuery.getType()) ? deleteQuery.getType() : getPersistentEntityFor(clazz).getIndexType(); + String indexName = isNotBlank(deleteQuery.getIndex()) ? deleteQuery.getIndex() + : getPersistentEntityFor(clazz).getIndexName(); + String typeName = isNotBlank(deleteQuery.getType()) ? deleteQuery.getType() + : getPersistentEntityFor(clazz).getIndexType(); Integer pageSize = deleteQuery.getPageSize() != null ? deleteQuery.getPageSize() : 1000; - Long scrollTimeInMillis = deleteQuery.getScrollTimeInMillis() != null ? deleteQuery.getScrollTimeInMillis() : 10000l; + Long scrollTimeInMillis = deleteQuery.getScrollTimeInMillis() != null ? deleteQuery.getScrollTimeInMillis() + : 10000l; - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(deleteQuery.getQuery()) - .withIndices(indexName) - .withTypes(typeName) - .withPageable(new PageRequest(0, pageSize)) - .build(); + SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(deleteQuery.getQuery()).withIndices(indexName) + .withTypes(typeName).withPageable(new PageRequest(0, pageSize)).build(); String scrollId = scan(searchQuery, scrollTimeInMillis, true); @@ -694,11 +718,11 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati } } - for(String id : ids) { + for (String id : ids) { bulkRequestBuilder.add(client.prepareDelete(indexName, typeName, id)); } - if(bulkRequestBuilder.numberOfActions() > 0) { + if (bulkRequestBuilder.numberOfActions() > 0) { bulkRequestBuilder.execute().actionGet(); } @@ -748,9 +772,11 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati private SearchRequestBuilder prepareScan(Query query, long scrollTimeInMillis, boolean noFields) { SearchRequestBuilder requestBuilder = client.prepareSearch(toArray(query.getIndices())).setSearchType(SCAN) - .setTypes(toArray(query.getTypes())) - .setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)).setFrom(0) - .setSize(query.getPageable().getPageSize()); + .setTypes(toArray(query.getTypes())).setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)).setFrom(0); + + if(query.getPageable() != Pageable.NONE){ + requestBuilder.setSize(query.getPageable().getPageSize()); + } if (!isEmpty(query.getFields())) { requestBuilder.addFields(toArray(query.getFields())); @@ -768,7 +794,8 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati Assert.notNull(criteriaQuery.getPageable(), "Query.pageable is required for scan & scroll"); QueryBuilder elasticsearchQuery = new CriteriaQueryProcessor().createQueryFromCriteria(criteriaQuery.getCriteria()); - QueryBuilder elasticsearchFilter = new CriteriaFilterProcessor().createFilterFromCriteria(criteriaQuery.getCriteria()); + QueryBuilder elasticsearchFilter = new CriteriaFilterProcessor() + .createFilterFromCriteria(criteriaQuery.getCriteria()); if (elasticsearchQuery != null) { requestBuilder.setQuery(elasticsearchQuery); @@ -797,16 +824,16 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati @Override public Page scroll(String scrollId, long scrollTimeInMillis, Class clazz) { - SearchResponse response = getSearchResponse(client.prepareSearchScroll(scrollId) - .setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)).execute()); - return resultsMapper.mapResults(response, clazz, null); + SearchResponse response = getSearchResponse( + client.prepareSearchScroll(scrollId).setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)).execute()); + return resultsMapper.mapResults(response, clazz, Pageable.NONE); } @Override public Page scroll(String scrollId, long scrollTimeInMillis, SearchResultMapper mapper) { - SearchResponse response = getSearchResponse(client.prepareSearchScroll(scrollId) - .setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)).execute()); - return mapper.mapResults(response, null, null); + SearchResponse response = getSearchResponse( + client.prepareSearchScroll(scrollId).setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)).execute()); + return mapper.mapResults(response, null, Pageable.NONE); } @Override @@ -960,8 +987,8 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati @Override public Map getSetting(String indexName) { Assert.notNull(indexName, "No index defined for getSettings"); - return client.admin().indices().getSettings(new GetSettingsRequest()) - .actionGet().getIndexToSettings().get(indexName).getAsMap(); + return client.admin().indices().getSettings(new GetSettingsRequest()).actionGet().getIndexToSettings() + .get(indexName).getAsMap(); } private SearchRequestBuilder prepareSearch(Query query, Class clazz) { @@ -982,7 +1009,7 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati searchRequestBuilder.setFetchSource(sourceFilter.getIncludes(), sourceFilter.getExcludes()); } - if (query.getPageable() != null) { + if (query.getPageable() != null && query.getPageable() != Pageable.NONE) { startRecord = query.getPageable().getPageNumber() * query.getPageable().getPageSize(); searchRequestBuilder.setSize(query.getPageable().getPageSize()); } @@ -994,8 +1021,8 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati if (query.getSort() != null) { for (Sort.Order order : query.getSort()) { - searchRequestBuilder.addSort(order.getProperty(), order.getDirection() == Sort.Direction.DESC ? SortOrder.DESC - : SortOrder.ASC); + searchRequestBuilder.addSort(order.getProperty(), + order.getDirection() == Sort.Direction.DESC ? SortOrder.DESC : SortOrder.ASC); } } @@ -1007,8 +1034,8 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati private IndexRequestBuilder prepareIndex(IndexQuery query) { try { - String indexName = isBlank(query.getIndexName()) ? retrieveIndexNameFromPersistentEntity(query.getObject() - .getClass())[0] : query.getIndexName(); + String indexName = isBlank(query.getIndexName()) + ? retrieveIndexNameFromPersistentEntity(query.getObject().getClass())[0] : query.getIndexName(); String type = isBlank(query.getType()) ? retrieveTypeFromPersistentEntity(query.getObject().getClass())[0] : query.getType(); @@ -1026,7 +1053,8 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati } else if (query.getSource() != null) { indexRequestBuilder = client.prepareIndex(indexName, type, query.getId()).setSource(query.getSource()); } else { - throw new ElasticsearchException("object or source is null, failed to index the document [id: " + query.getId() + "]"); + throw new ElasticsearchException( + "object or source is null, failed to index the document [id: " + query.getId() + "]"); } if (query.getVersion() != null) { indexRequestBuilder.setVersion(query.getVersion()); @@ -1077,40 +1105,44 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati public Boolean removeAlias(AliasQuery query) { Assert.notNull(query.getIndexName(), "No index defined for Alias"); Assert.notNull(query.getAliasName(), "No alias defined"); - return client.admin().indices().prepareAliases().removeAlias(query.getIndexName(), query.getAliasName()) - .execute().actionGet().isAcknowledged(); + return client.admin().indices().prepareAliases().removeAlias(query.getIndexName(), query.getAliasName()).execute() + .actionGet().isAcknowledged(); } @Override public List queryForAlias(String indexName) { - return client.admin().indices().getAliases(new GetAliasesRequest().indices(indexName)) - .actionGet().getAliases().get(indexName); + return client.admin().indices().getAliases(new GetAliasesRequest().indices(indexName)).actionGet().getAliases() + .get(indexName); } @Override public ElasticsearchPersistentEntity getPersistentEntityFor(Class clazz) { Assert.isTrue(clazz.isAnnotationPresent(Document.class), "Unable to identify index name. " + clazz.getSimpleName() + " is not a Document. Make sure the document class is annotated with @Document(indexName=\"foo\")"); - return elasticsearchConverter.getMappingContext().getPersistentEntity(clazz); + return elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(clazz); } private String getPersistentEntityId(Object entity) { ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(entity.getClass()); - Object identifier = persistentEntity.getIdentifierAccessor(entity).getIdentifier(); + Optional identifier = persistentEntity.getIdentifierAccessor(entity).getIdentifier(); - return identifier == null ? null : String.valueOf(identifier); + return identifier.map(String::valueOf).orElse(null); } private void setPersistentEntityId(Object entity, String id) { ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(entity.getClass()); - PersistentProperty idProperty = persistentEntity.getIdProperty(); + Optional idProperty = persistentEntity.getIdProperty(); // Only deal with String because ES generated Ids are strings ! - if (idProperty != null && idProperty.getType().isAssignableFrom(String.class)) { - persistentEntity.getPropertyAccessor(entity).setProperty(idProperty,id); - } + + idProperty.ifPresent(property -> { + + if (property.getType().isAssignableFrom(String.class)) { + persistentEntity.getPropertyAccessor(entity).setProperty(property, Optional.ofNullable(id)); + } + }); } private void setPersistentEntityIndexAndType(Query query, Class clazz) { @@ -1124,14 +1156,14 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati private String[] retrieveIndexNameFromPersistentEntity(Class clazz) { if (clazz != null) { - return new String[]{getPersistentEntityFor(clazz).getIndexName()}; + return new String[] { getPersistentEntityFor(clazz).getIndexName() }; } return null; } private String[] retrieveTypeFromPersistentEntity(Class clazz) { if (clazz != null) { - return new String[]{getPersistentEntityFor(clazz).getIndexType()}; + return new String[] { getPersistentEntityFor(clazz).getIndexType() }; } return null; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java index b3127ad7c..fe7a8484c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ */ package org.springframework.data.elasticsearch.core.mapping; +import java.util.Optional; + import org.springframework.data.mapping.PersistentEntity; /** @@ -22,8 +24,8 @@ import org.springframework.data.mapping.PersistentEntity; * * @author Rizwan Idrees * @author Mohsin Husen + * @author Mark Paluch */ - public interface ElasticsearchPersistentEntity extends PersistentEntity { String getIndexName(); @@ -40,11 +42,11 @@ public interface ElasticsearchPersistentEntity extends PersistentEntity getVersionProperty(); - String getParentType(); + Optional getParentType(); - ElasticsearchPersistentProperty getParentIdProperty(); + Optional getParentIdProperty(); String settingPath(); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchMappingContext.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchMappingContext.java index ee1efb095..281a5a007 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchMappingContext.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchMappingContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,13 +15,11 @@ */ package org.springframework.data.elasticsearch.core.mapping; -import java.beans.PropertyDescriptor; -import java.lang.reflect.Field; - import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.data.mapping.context.AbstractMappingContext; +import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.util.TypeInformation; @@ -30,8 +28,8 @@ import org.springframework.data.util.TypeInformation; * * @author Rizwan Idrees * @author Mohsin Husen + * @author Mark Paluch */ - public class SimpleElasticsearchMappingContext extends AbstractMappingContext, ElasticsearchPersistentProperty> implements ApplicationContextAware { @@ -39,8 +37,8 @@ public class SimpleElasticsearchMappingContext extends @Override protected SimpleElasticsearchPersistentEntity createPersistentEntity(TypeInformation typeInformation) { - final SimpleElasticsearchPersistentEntity persistentEntity = - new SimpleElasticsearchPersistentEntity(typeInformation); + final SimpleElasticsearchPersistentEntity persistentEntity = new SimpleElasticsearchPersistentEntity( + typeInformation); if (context != null) { persistentEntity.setApplicationContext(context); } @@ -48,9 +46,9 @@ public class SimpleElasticsearchMappingContext extends } @Override - protected ElasticsearchPersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor, - SimpleElasticsearchPersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { - return new SimpleElasticsearchPersistentProperty(field, descriptor, owner, simpleTypeHolder); + protected ElasticsearchPersistentProperty createPersistentProperty(Property property, + SimpleElasticsearchPersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { + return new SimpleElasticsearchPersistentProperty(property, owner, simpleTypeHolder); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java index f4afb13d1..f7dee0249 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.springframework.data.elasticsearch.core.mapping; import static org.springframework.util.StringUtils.*; import java.util.Locale; +import java.util.Optional; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; @@ -41,6 +42,7 @@ import org.springframework.util.Assert; * @param * @author Rizwan Idrees * @author Mohsin Husen + * @author Mark Paluch */ public class SimpleElasticsearchPersistentEntity extends BasicPersistentEntity implements ElasticsearchPersistentEntity, ApplicationContextAware { @@ -55,8 +57,8 @@ public class SimpleElasticsearchPersistentEntity extends BasicPersistentEntit private short replicas; private String refreshInterval; private String indexStoreType; - private String parentType; - private ElasticsearchPersistentProperty parentIdProperty; + private Optional parentType = Optional.empty(); + private Optional parentIdProperty = Optional.empty(); private String settingPath; private boolean createIndexAndMapping; @@ -129,12 +131,12 @@ public class SimpleElasticsearchPersistentEntity extends BasicPersistentEntit } @Override - public String getParentType() { + public Optional getParentType() { return parentType; } @Override - public ElasticsearchPersistentProperty getParentIdProperty() { + public Optional getParentIdProperty() { return parentIdProperty; } @@ -152,16 +154,15 @@ public class SimpleElasticsearchPersistentEntity extends BasicPersistentEntit public void addPersistentProperty(ElasticsearchPersistentProperty property) { super.addPersistentProperty(property); - if (property.getField() != null) { - Parent parent = property.getField().getAnnotation(Parent.class); - if (parent != null) { - Assert.isNull(this.parentIdProperty, "Only one field can hold a @Parent annotation"); - Assert.isNull(this.parentType, "Only one field can hold a @Parent annotation"); - Assert.isTrue(property.getType() == String.class, "Parent ID property should be String"); - this.parentIdProperty = property; - this.parentType = parent.type(); - } - } + Optional annotation = property.findAnnotation(Parent.class); + + annotation.ifPresent(parent -> { + Assert.isTrue(!this.parentIdProperty.isPresent(), "Only one field can hold a @Parent annotation"); + Assert.isTrue(!this.parentType.isPresent(), "Only one field can hold a @Parent annotation"); + Assert.isTrue(property.getType() == String.class, "Parent ID property should be String"); + this.parentIdProperty = Optional.of(property); + this.parentType = Optional.of(parent.type()); + }); if (property.isVersionProperty()) { Assert.isTrue(property.getType() == Long.class, "Version property should be Long"); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java index ea1765ec1..6e350be75 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,14 +15,13 @@ */ package org.springframework.data.elasticsearch.core.mapping; -import java.beans.PropertyDescriptor; -import java.lang.reflect.Field; import java.util.HashSet; import java.util.Set; import org.springframework.data.mapping.Association; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty; +import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.SimpleTypeHolder; /** @@ -30,6 +29,7 @@ import org.springframework.data.mapping.model.SimpleTypeHolder; * * @author Rizwan Idrees * @author Mohsin Husen + * @author Mark Paluch */ public class SimpleElasticsearchPersistentProperty extends AnnotationBasedPersistentProperty implements ElasticsearchPersistentProperty { @@ -43,19 +43,19 @@ public class SimpleElasticsearchPersistentProperty extends SUPPORTED_ID_PROPERTY_NAMES.add("documentId"); } - public SimpleElasticsearchPersistentProperty(Field field, PropertyDescriptor propertyDescriptor, - PersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { - super(field, propertyDescriptor, owner, simpleTypeHolder); + public SimpleElasticsearchPersistentProperty(Property property, + PersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { + super(property, owner, simpleTypeHolder); } @Override public String getFieldName() { - return field.getName(); + return getProperty().getName(); } @Override public boolean isIdProperty() { - return super.isIdProperty() || (field != null ? SUPPORTED_ID_PROPERTY_NAMES.contains(getFieldName()) : false); + return super.isIdProperty() || SUPPORTED_ID_PROPERTY_NAMES.contains(getFieldName()); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/CriteriaQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/CriteriaQuery.java index d760e665e..23e540140 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/CriteriaQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/CriteriaQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,24 +23,26 @@ import org.springframework.util.Assert; * * @author Rizwan Idrees * @author Mohsin Husen + * @author Mark Paluch */ public class CriteriaQuery extends AbstractQuery { private Criteria criteria; - private CriteriaQuery() { - } + private CriteriaQuery() {} public CriteriaQuery(Criteria criteria) { - this(criteria, null); + this(criteria, Pageable.NONE); } public CriteriaQuery(Criteria criteria, Pageable pageable) { + + Assert.notNull(criteria, "Criteria must not be null!"); + Assert.notNull(pageable, "Pageable must not be null!"); + this.criteria = criteria; this.pageable = pageable; - if (pageable != null) { - this.addSort(pageable.getSort()); - } + this.addSort(pageable.getSort()); } public static final Query fromQuery(CriteriaQuery source) { diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/cdi/ElasticsearchRepositoryBean.java b/src/main/java/org/springframework/data/elasticsearch/repository/cdi/ElasticsearchRepositoryBean.java index 88daf135d..15a0b905b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/cdi/ElasticsearchRepositoryBean.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/cdi/ElasticsearchRepositoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,11 +15,13 @@ */ package org.springframework.data.elasticsearch.repository.cdi; +import java.lang.annotation.Annotation; +import java.util.Optional; +import java.util.Set; + import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; -import java.lang.annotation.Annotation; -import java.util.Set; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.repository.support.ElasticsearchRepositoryFactory; @@ -28,7 +30,8 @@ import org.springframework.data.repository.config.CustomRepositoryImplementation import org.springframework.util.Assert; /** - * Uses CdiRepositoryBean to create ElasticsearchRepository instances. + * Uses {@link CdiRepositoryBean} to create + * {@link org.springframework.data.elasticsearch.repository.ElasticsearchRepository} instances. * * @author Rizwan Idrees * @author Mohsin Husen @@ -46,24 +49,36 @@ public class ElasticsearchRepositoryBean extends CdiRepositoryBean { * @param repositoryType must not be {@literal null}. * @param beanManager must not be {@literal null}. * @param detector detector for the custom {@link org.springframework.data.repository.Repository} implementations - * {@link CustomRepositoryImplementationDetector}, can be {@literal null}. + * {@link CustomRepositoryImplementationDetector}, can be {@literal null}. */ public ElasticsearchRepositoryBean(Bean operations, Set qualifiers, - Class repositoryType, BeanManager beanManager, CustomRepositoryImplementationDetector detector) { + Class repositoryType, BeanManager beanManager, Optional detector) { super(qualifiers, repositoryType, beanManager, detector); Assert.notNull(operations, "Cannot create repository with 'null' for ElasticsearchOperations."); this.elasticsearchOperationsBean = operations; } + /* (non-Javadoc) + * @see org.springframework.data.repository.cdi.CdiRepositoryBean#create(javax.enterprise.context.spi.CreationalContext, java.lang.Class, java.util.Optional) + */ @Override - protected T create(CreationalContext creationalContext, Class repositoryType, Object customImplementation) { + protected T create(CreationalContext creationalContext, Class repositoryType, + Optional customImplementation) { + ElasticsearchOperations elasticsearchOperations = getDependencyInstance(elasticsearchOperationsBean, ElasticsearchOperations.class); - return new ElasticsearchRepositoryFactory(elasticsearchOperations).getRepository(repositoryType, - customImplementation); + + ElasticsearchRepositoryFactory factory = new ElasticsearchRepositoryFactory(elasticsearchOperations); + + return customImplementation // + .map(o -> factory.getRepository(repositoryType, o)) // + .orElseGet(() -> factory.getRepository(repositoryType)); } + /* (non-Javadoc) + * @see org.springframework.data.repository.cdi.CdiRepositoryBean#getScope() + */ @Override public Class getScope() { return elasticsearchOperationsBean.getScope(); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/cdi/ElasticsearchRepositoryExtension.java b/src/main/java/org/springframework/data/elasticsearch/repository/cdi/ElasticsearchRepositoryExtension.java index 602d19bae..8d027c241 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/cdi/ElasticsearchRepositoryExtension.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/cdi/ElasticsearchRepositoryExtension.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,18 +15,20 @@ */ package org.springframework.data.elasticsearch.repository.cdi; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; + import javax.enterprise.event.Observes; import javax.enterprise.inject.UnsatisfiedResolutionException; import javax.enterprise.inject.spi.AfterBeanDiscovery; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import javax.enterprise.inject.spi.ProcessBean; -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.repository.cdi.CdiRepositoryBean; @@ -67,7 +69,7 @@ public class ElasticsearchRepositoryExtension extends CdiRepositoryExtensionSupp } private CdiRepositoryBean createRepositoryBean(Class repositoryType, Set qualifiers, - BeanManager beanManager) { + BeanManager beanManager) { Bean elasticsearchOperationsBean = this.elasticsearchOperationsMap.get(qualifiers); @@ -77,6 +79,6 @@ public class ElasticsearchRepositoryExtension extends CdiRepositoryExtensionSupp } return new ElasticsearchRepositoryBean(elasticsearchOperationsBean, qualifiers, repositoryType, beanManager, - getCustomImplementationDetector()); + Optional.ofNullable(getCustomImplementationDetector())); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java index 3cd3bc098..23de735f9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java @@ -23,6 +23,7 @@ import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Optional; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.index.query.QueryBuilder; @@ -45,16 +46,15 @@ import org.springframework.util.Assert; * @author Kevin Leturc * @author Mark Paluch */ -public abstract class AbstractElasticsearchRepository implements - ElasticsearchRepository { +public abstract class AbstractElasticsearchRepository + implements ElasticsearchRepository { static final Logger LOGGER = LoggerFactory.getLogger(AbstractElasticsearchRepository.class); protected ElasticsearchOperations elasticsearchOperations; protected Class entityClass; protected ElasticsearchEntityInformation entityInformation; - public AbstractElasticsearchRepository() { - } + public AbstractElasticsearchRepository() {} public AbstractElasticsearchRepository(ElasticsearchOperations elasticsearchOperations) { @@ -64,7 +64,7 @@ public abstract class AbstractElasticsearchRepository metadata, - ElasticsearchOperations elasticsearchOperations) { + ElasticsearchOperations elasticsearchOperations) { this(elasticsearchOperations); Assert.notNull(metadata, "ElasticsearchEntityInformation must not be null!"); @@ -94,17 +94,17 @@ public abstract class AbstractElasticsearchRepository findOne(ID id) { GetQuery query = new GetQuery(); query.setId(stringIdRepresentation(id)); - return elasticsearchOperations.queryForObject(query, getEntityClass()); + return Optional.ofNullable(elasticsearchOperations.queryForObject(query, getEntityClass())); } @Override public Iterable findAll() { int itemCount = (int) this.count(); if (itemCount == 0) { - return new PageImpl(Collections.emptyList()); + return new PageImpl(Collections. emptyList()); } return this.findAll(new PageRequest(0, Math.max(1, itemCount))); } @@ -119,7 +119,7 @@ public abstract class AbstractElasticsearchRepository findAll(Sort sort) { int itemCount = (int) this.count(); if (itemCount == 0) { - return new PageImpl(Collections.emptyList()); + return new PageImpl(Collections. emptyList()); } SearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(new PageRequest(0, itemCount, sort)).build(); @@ -129,9 +129,7 @@ public abstract class AbstractElasticsearchRepository findAll(Iterable ids) { Assert.notNull(ids, "ids can't be null."); - SearchQuery query = new NativeSearchQueryBuilder() - .withIds(stringIdsRepresentation(ids)) - .build(); + SearchQuery query = new NativeSearchQueryBuilder().withIds(stringIdsRepresentation(ids)).build(); return elasticsearchOperations.multiGet(query, getEntityClass()); } @@ -188,7 +186,7 @@ public abstract class AbstractElasticsearchRepository(Collections.emptyList()); + return new PageImpl(Collections. emptyList()); } searchQuery.setPageable(new PageRequest(0, count)); return elasticsearchOperations.queryForPage(searchQuery, getEntityClass()); @@ -308,10 +306,7 @@ public abstract class AbstractElasticsearchRepository stringIdsRepresentation(Iterable ids) { @@ -326,16 +321,10 @@ public abstract class AbstractElasticsearchRepository ElasticsearchEntityInformation getEntityInformation(Class domainClass) { ElasticsearchPersistentEntity persistentEntity = (ElasticsearchPersistentEntity) mappingContext - .getPersistentEntity(domainClass); + .getRequiredPersistentEntity(domainClass); Assert.notNull(persistentEntity, String.format("Unable to obtain mapping metadata for %s!", domainClass)); Assert.notNull(persistentEntity.getIdProperty(), String.format("No id property found for %s!", domainClass)); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactory.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactory.java index 3ee1ceef9..2e965c63e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactory.java @@ -15,10 +15,11 @@ */ package org.springframework.data.elasticsearch.repository.support; -import static org.springframework.data.querydsl.QueryDslUtils.*; +import static org.springframework.data.querydsl.QuerydslUtils.*; import java.io.Serializable; import java.lang.reflect.Method; +import java.util.Optional; import java.util.UUID; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; @@ -27,12 +28,14 @@ import org.springframework.data.elasticsearch.repository.query.ElasticsearchPart import org.springframework.data.elasticsearch.repository.query.ElasticsearchQueryMethod; import org.springframework.data.elasticsearch.repository.query.ElasticsearchStringQuery; import org.springframework.data.projection.ProjectionFactory; -import org.springframework.data.querydsl.QueryDslPredicateExecutor; +import org.springframework.data.querydsl.QuerydslPredicateExecutor; import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.support.RepositoryFactorySupport; +import org.springframework.data.repository.query.EvaluationContextProvider; import org.springframework.data.repository.query.QueryLookupStrategy; +import org.springframework.data.repository.query.QueryLookupStrategy.Key; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.util.Assert; @@ -55,8 +58,8 @@ public class ElasticsearchRepositoryFactory extends RepositoryFactorySupport { Assert.notNull(elasticsearchOperations, "ElasticsearchOperations must not be null!"); this.elasticsearchOperations = elasticsearchOperations; - this.entityInformationCreator = new ElasticsearchEntityInformationCreatorImpl(elasticsearchOperations - .getElasticsearchConverter().getMappingContext()); + this.entityInformationCreator = new ElasticsearchEntityInformationCreatorImpl( + elasticsearchOperations.getElasticsearchConverter().getMappingContext()); } @Override @@ -65,9 +68,10 @@ public class ElasticsearchRepositoryFactory extends RepositoryFactorySupport { } @Override - @SuppressWarnings({"rawtypes", "unchecked"}) + @SuppressWarnings({ "rawtypes", "unchecked" }) protected Object getTargetRepository(RepositoryInformation metadata) { - return getTargetRepositoryViaReflection(metadata,getEntityInformation(metadata.getDomainType()), elasticsearchOperations); + return getTargetRepositoryViaReflection(metadata, getEntityInformation(metadata.getDomainType()), + elasticsearchOperations); } @Override @@ -75,8 +79,7 @@ public class ElasticsearchRepositoryFactory extends RepositoryFactorySupport { if (isQueryDslRepository(metadata.getRepositoryInterface())) { throw new IllegalArgumentException("QueryDsl Support has not been implemented yet."); } - if (Integer.class.isAssignableFrom(metadata.getIdType()) - || Long.class.isAssignableFrom(metadata.getIdType()) + if (Integer.class.isAssignableFrom(metadata.getIdType()) || Long.class.isAssignableFrom(metadata.getIdType()) || Double.class.isAssignableFrom(metadata.getIdType())) { return NumberKeyedRepository.class; } else if (metadata.getIdType() == String.class) { @@ -89,17 +92,18 @@ public class ElasticsearchRepositoryFactory extends RepositoryFactorySupport { } private static boolean isQueryDslRepository(Class repositoryInterface) { - return QUERY_DSL_PRESENT && QueryDslPredicateExecutor.class.isAssignableFrom(repositoryInterface); + return QUERY_DSL_PRESENT && QuerydslPredicateExecutor.class.isAssignableFrom(repositoryInterface); } @Override - protected QueryLookupStrategy getQueryLookupStrategy(QueryLookupStrategy.Key key) { - return new ElasticsearchQueryLookupStrategy(); + protected Optional getQueryLookupStrategy(Key key, + EvaluationContextProvider evaluationContextProvider) { + return Optional.of(new ElasticsearchQueryLookupStrategy()); } private class ElasticsearchQueryLookupStrategy implements QueryLookupStrategy { - - /* + + /* * (non-Javadoc) * @see org.springframework.data.repository.query.QueryLookupStrategy#resolveQuery(java.lang.reflect.Method, org.springframework.data.repository.core.RepositoryMetadata, org.springframework.data.projection.ProjectionFactory, org.springframework.data.repository.core.NamedQueries) */ diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/MappingElasticsearchEntityInformation.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/MappingElasticsearchEntityInformation.java index d43553de0..169597aa4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/MappingElasticsearchEntityInformation.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/MappingElasticsearchEntityInformation.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,13 +16,13 @@ package org.springframework.data.elasticsearch.repository.support; import java.io.Serializable; +import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.repository.core.support.PersistentEntityInformation; -import org.springframework.util.Assert; /** * Elasticsearch specific implementation of @@ -34,9 +34,10 @@ import org.springframework.util.Assert; * @author Mohsin Husen * @author Ryan Henszey * @author Oliver Gierke + * @author Mark Paluch */ -public class MappingElasticsearchEntityInformation extends PersistentEntityInformation - implements ElasticsearchEntityInformation { +public class MappingElasticsearchEntityInformation + extends PersistentEntityInformation implements ElasticsearchEntityInformation { private static final Logger logger = LoggerFactory.getLogger(MappingElasticsearchEntityInformation.class); private final ElasticsearchPersistentEntity entityMetadata; @@ -54,13 +55,15 @@ public class MappingElasticsearchEntityInformation e this.type = type; } - @Override public String getIdAttribute() { - Assert.notNull(entityMetadata.getIdProperty(), "Unable to identify 'id' property in class " - + entityMetadata.getType().getSimpleName() - + ". Make sure the 'id' property is annotated with @Id or named as 'id' or 'documentId' "); - return entityMetadata.getIdProperty().getFieldName(); + + ElasticsearchPersistentProperty property = entityMetadata.getIdProperty() + .orElseThrow(() -> new IllegalArgumentException(String.format( + "Unable to identify 'id' property in class %s. Make sure the 'id' property is annotated with @Id or named as 'id' or 'documentId'", + entityMetadata.getType().getSimpleName()))); + + return property.getFieldName(); } @Override @@ -75,27 +78,30 @@ public class MappingElasticsearchEntityInformation e @Override public Long getVersion(T entity) { - ElasticsearchPersistentProperty versionProperty = entityMetadata.getVersionProperty(); + + Optional versionProperty = entityMetadata.getVersionProperty(); try { - if (versionProperty != null) { - return (Long) entityMetadata.getPropertyAccessor(entity).getProperty(versionProperty); - } + + return (Long) versionProperty // + .flatMap(property -> entityMetadata.getPropertyAccessor(entity).getProperty(property)) // + .orElse(null); + } catch (Exception e) { throw new IllegalStateException("failed to load version field", e); } - return null; } @Override public String getParentId(T entity) { - ElasticsearchPersistentProperty parentProperty = entityMetadata.getParentIdProperty(); + + Optional parentProperty = entityMetadata.getParentIdProperty(); try { - if (parentProperty != null) { - return (String) entityMetadata.getPropertyAccessor(entity).getProperty(parentProperty); - } + + return (String) parentProperty // + .flatMap(property -> entityMetadata.getPropertyAccessor(entity).getProperty(property)) // + .orElse(null); } catch (Exception e) { throw new IllegalStateException("failed to load parent ID: " + e, e); } - return null; } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/DefaultResultMapperTests.java b/src/test/java/org/springframework/data/elasticsearch/core/DefaultResultMapperTests.java index 542df6ac2..66b8e7e95 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/DefaultResultMapperTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/DefaultResultMapperTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,11 +41,9 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.springframework.data.annotation.AccessType; -import org.springframework.data.annotation.Id; import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.annotations.Document; -import org.springframework.data.elasticsearch.core.DefaultResultMapperTests.ImmutableEntity; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; import org.springframework.data.elasticsearch.entities.Car; @@ -53,6 +51,7 @@ import org.springframework.data.elasticsearch.entities.Car; /** * @author Artur Konczak * @author Mohsin Husen + * @author Mark Paluch */ public class DefaultResultMapperTests { @@ -85,7 +84,7 @@ public class DefaultResultMapperTests { when(response.getAggregations()).thenReturn(aggregations); //When - AggregatedPage page = (AggregatedPage) resultMapper.mapResults(response, Car.class, null); + AggregatedPage page = (AggregatedPage) resultMapper.mapResults(response, Car.class, Pageable.NONE); //Then page.hasFacets(); @@ -103,7 +102,7 @@ public class DefaultResultMapperTests { when(response.getHits()).thenReturn(searchHits); //When - Page page = resultMapper.mapResults(response, Car.class, null); + Page page = resultMapper.mapResults(response, Car.class, Pageable.NONE); //Then assertThat(page.hasContent(), is(true)); @@ -121,7 +120,7 @@ public class DefaultResultMapperTests { when(response.getHits()).thenReturn(searchHits); //When - Page page = resultMapper.mapResults(response, Car.class, null); + Page page = resultMapper.mapResults(response, Car.class, Pageable.NONE); //Then assertThat(page.hasContent(), is(true)); @@ -143,19 +142,19 @@ public class DefaultResultMapperTests { assertThat(result.getModel(), is("Grat")); assertThat(result.getName(), is("Ford")); } - + /** * @see DATAES-281. */ @Test public void setsIdentifierOnImmutableType() { - + GetResponse response = mock(GetResponse.class); when(response.getSourceAsString()).thenReturn("{}"); when(response.getId()).thenReturn("identifier"); - + ImmutableEntity result = resultMapper.mapResult(response, ImmutableEntity.class); - + assertThat(result, is(notNullValue())); assertThat(result.getId(), is("identifier")); } @@ -193,7 +192,7 @@ public class DefaultResultMapperTests { result.put("model", new InternalSearchHitField("model", Arrays.asList(model))); return result; } - + @Document(indexName = "someIndex") @NoArgsConstructor(force = true) @Getter diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java index bd891aba2..9039dc0f2 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,18 +16,20 @@ package org.springframework.data.elasticsearch.core.mapping; import java.beans.IntrospectionException; -import java.beans.PropertyDescriptor; import org.junit.Test; import org.springframework.data.annotation.Version; import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; +import org.springframework.util.ReflectionUtils; /** * @author Rizwan Idrees * @author Mohsin Husen + * @author Mark Paluch */ public class SimpleElasticsearchPersistentEntityTests { @@ -35,46 +37,43 @@ public class SimpleElasticsearchPersistentEntityTests { public void shouldThrowExceptionGivenVersionPropertyIsNotLong() throws NoSuchFieldException, IntrospectionException { // given TypeInformation typeInformation = ClassTypeInformation.from(EntityWithWrongVersionType.class); - SimpleElasticsearchPersistentProperty persistentProperty = new SimpleElasticsearchPersistentProperty( - EntityWithWrongVersionType.class.getDeclaredField("version"), new PropertyDescriptor("version", - EntityWithWrongVersionType.class), new SimpleElasticsearchPersistentEntity( - typeInformation), new SimpleTypeHolder() - ); + SimpleElasticsearchPersistentEntity entity = new SimpleElasticsearchPersistentEntity<>( + typeInformation); + + SimpleElasticsearchPersistentProperty persistentProperty = createProperty(entity, "version"); // when - new SimpleElasticsearchPersistentEntity(typeInformation).addPersistentProperty(persistentProperty); + entity.addPersistentProperty(persistentProperty); } @Test(expected = MappingException.class) - public void shouldThrowExceptionGivenMultipleVersionPropertiesArePresent() throws NoSuchFieldException, - IntrospectionException { + public void shouldThrowExceptionGivenMultipleVersionPropertiesArePresent() + throws NoSuchFieldException, IntrospectionException { // given TypeInformation typeInformation = ClassTypeInformation.from(EntityWithMultipleVersionField.class); - SimpleElasticsearchPersistentProperty persistentProperty1 = new SimpleElasticsearchPersistentProperty( - EntityWithMultipleVersionField.class.getDeclaredField("version1"), new PropertyDescriptor("version1", - EntityWithMultipleVersionField.class), - new SimpleElasticsearchPersistentEntity(typeInformation), - new SimpleTypeHolder() - ); - - SimpleElasticsearchPersistentProperty persistentProperty2 = new SimpleElasticsearchPersistentProperty( - EntityWithMultipleVersionField.class.getDeclaredField("version2"), new PropertyDescriptor("version2", - EntityWithMultipleVersionField.class), - new SimpleElasticsearchPersistentEntity(typeInformation), - new SimpleTypeHolder() - ); - - SimpleElasticsearchPersistentEntity simpleElasticsearchPersistentEntity = new SimpleElasticsearchPersistentEntity( + SimpleElasticsearchPersistentEntity entity = new SimpleElasticsearchPersistentEntity<>( typeInformation); - simpleElasticsearchPersistentEntity.addPersistentProperty(persistentProperty1); + + SimpleElasticsearchPersistentProperty persistentProperty1 = createProperty(entity, "version1"); + + SimpleElasticsearchPersistentProperty persistentProperty2 = createProperty(entity, "version2"); + + entity.addPersistentProperty(persistentProperty1); // when - simpleElasticsearchPersistentEntity.addPersistentProperty(persistentProperty2); + entity.addPersistentProperty(persistentProperty2); + } + + private static SimpleElasticsearchPersistentProperty createProperty(SimpleElasticsearchPersistentEntity entity, + String field) { + + Property property = Property.of(ReflectionUtils.findField(entity.getTypeInformation().getType(), field)); + return new SimpleElasticsearchPersistentProperty(property, entity, new SimpleTypeHolder()); + } private class EntityWithWrongVersionType { - @Version - private String version; + @Version private String version; public String getVersion() { return version; @@ -87,10 +86,8 @@ public class SimpleElasticsearchPersistentEntityTests { private class EntityWithMultipleVersionField { - @Version - private Long version1; - @Version - private Long version2; + @Version private Long version1; + @Version private Long version2; public Long getVersion1() { return version1; diff --git a/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java index afc9eb84c..4ef125e71 100644 --- a/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,8 @@ package org.springframework.data.elasticsearch.immutable; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; +import java.util.Optional; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -29,6 +31,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author Young Gu * @author Oliver Gierke + * @author Mark Paluch */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:immutable-repository-test.xml") @@ -37,29 +40,34 @@ public class ImmutableElasticsearchRepositoryTests { @Autowired ImmutableElasticsearchRepository repository; @Autowired ElasticsearchOperations operations; - @Before public void before() { - + operations.deleteIndex(ImmutableEntity.class); operations.createIndex(ImmutableEntity.class); operations.refresh(ImmutableEntity.class); } - + /** * @see DATAES-281 */ @Test public void shouldSaveAndFindImmutableDocument() { - + // when ImmutableEntity entity = repository.save(new ImmutableEntity("test name")); assertThat(entity.getId(), is(notNullValue())); - + // then - ImmutableEntity entityFromElasticSearch = repository.findOne(entity.getId()); - - assertThat(entityFromElasticSearch.getName(), is("test name")); - assertThat(entityFromElasticSearch.getId(), is(entity.getId())); + Optional entityFromElasticSearch = repository.findOne(entity.getId()); + + assertThat(entityFromElasticSearch.isPresent(), is(true)); + + entityFromElasticSearch.ifPresent(immutableEntity -> { + + assertThat(immutableEntity.getName(), is("test name")); + assertThat(immutableEntity.getId(), is(entity.getId())); + }); + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiProductRepository.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiProductRepository.java index 89afa882d..26286fa08 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiProductRepository.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiProductRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,14 +15,17 @@ */ package org.springframework.data.elasticsearch.repositories.cdi; +import java.util.Optional; + import org.springframework.data.elasticsearch.entities.Product; import org.springframework.data.repository.CrudRepository; /** * @author Mohsin Husen * @author Oliver Gierke + * @author Mark Paluch */ public interface CdiProductRepository extends CrudRepository { - Product findOne(String id); + Optional findOne(String id); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java index ae55b1711..3b5bd3cd7 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,8 @@ package org.springframework.data.elasticsearch.repositories.cdi; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; +import java.util.Optional; + import org.apache.webbeans.cditest.CdiTestContainer; import org.apache.webbeans.cditest.CdiTestContainerLoader; import org.junit.AfterClass; @@ -70,10 +72,13 @@ public class CdiRepositoryTests { assertTrue(repository.exists(bean.getId())); - Product retrieved = repository.findOne(bean.getId()); - assertNotNull(retrieved); - assertEquals(bean.getId(), retrieved.getId()); - assertEquals(bean.getName(), retrieved.getName()); + Optional retrieved = repository.findOne(bean.getId()); + + assertTrue(retrieved.isPresent()); + retrieved.ifPresent(product -> { + assertEquals(bean.getId(), product.getId()); + assertEquals(bean.getName(), product.getName()); + }); assertEquals(1, repository.count()); @@ -83,7 +88,7 @@ public class CdiRepositoryTests { assertEquals(0, repository.count()); retrieved = repository.findOne(bean.getId()); - assertNull(retrieved); + assertFalse(retrieved.isPresent()); } /** @@ -101,10 +106,13 @@ public class CdiRepositoryTests { assertTrue(qualifiedProductRepository.exists(bean.getId())); - Product retrieved = qualifiedProductRepository.findOne(bean.getId()); - assertNotNull(retrieved); - assertEquals(bean.getId(), retrieved.getId()); - assertEquals(bean.getName(), retrieved.getName()); + Optional retrieved = qualifiedProductRepository.findOne(bean.getId()); + + assertTrue(retrieved.isPresent()); + retrieved.ifPresent(product -> { + assertEquals(bean.getId(), product.getId()); + assertEquals(bean.getName(), product.getName()); + }); assertEquals(1, qualifiedProductRepository.count()); @@ -114,7 +122,7 @@ public class CdiRepositoryTests { assertEquals(0, qualifiedProductRepository.count()); retrieved = qualifiedProductRepository.findOne(bean.getId()); - assertNull(retrieved); + assertFalse(retrieved.isPresent()); } /** diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java index 9e6b13bf7..f74d7ab2b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,9 @@ package org.springframework.data.elasticsearch.repositories.geo; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; +import java.util.Locale; +import java.util.Optional; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -29,18 +32,16 @@ import org.springframework.data.geo.Point; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import java.util.Locale; - - +/** + * @author Mark Paluch + */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:/repository-spring-data-geo-support.xml") public class SpringDataGeoRepositoryTests { - @Autowired - private ElasticsearchTemplate template; + @Autowired ElasticsearchTemplate template; - @Autowired - private SpringDataGeoRepository repository; + @Autowired SpringDataGeoRepository repository; @Before public void init() { @@ -52,25 +53,25 @@ public class SpringDataGeoRepositoryTests { @Test public void shouldSaveAndLoadGeoPoints() { - //given + // given final Point point = new Point(15, 25); - GeoEntity entity = GeoEntity.builder() - .pointA(point) - .pointB(new GeoPoint(point.getX(), point.getY())) - .pointC(toGeoString(point)) - .pointD(toGeoArray(point)) - .build(); - //when - entity = repository.save(entity); - GeoEntity result = repository.findOne(entity.getId()); - //then + GeoEntity entity = GeoEntity.builder().pointA(point).pointB(new GeoPoint(point.getX(), point.getY())) + .pointC(toGeoString(point)).pointD(toGeoArray(point)).build(); + // when + GeoEntity saved = repository.save(entity); + Optional result = repository.findOne(entity.getId()); + // then - assertThat(entity.getPointA().getX(), is(result.getPointA().getX())); - assertThat(entity.getPointA().getY(), is(result.getPointA().getY())); - assertThat(entity.getPointB().getLat(), is(result.getPointB().getLat())); - assertThat(entity.getPointB().getLon(), is(result.getPointB().getLon())); - assertThat(entity.getPointC(), is(result.getPointC())); - assertThat(entity.getPointD(), is(result.getPointD())); + assertThat(result.isPresent(), is(true)); + result.ifPresent(geoEntity -> { + + assertThat(saved.getPointA().getX(), is(geoEntity.getPointA().getX())); + assertThat(saved.getPointA().getY(), is(geoEntity.getPointA().getY())); + assertThat(saved.getPointB().getLat(), is(geoEntity.getPointB().getLat())); + assertThat(saved.getPointB().getLon(), is(geoEntity.getPointB().getLon())); + assertThat(saved.getPointC(), is(geoEntity.getPointC())); + assertThat(saved.getPointD(), is(geoEntity.getPointD())); + }); } private String toGeoString(Point point) { @@ -78,8 +79,6 @@ public class SpringDataGeoRepositoryTests { } private double[] toGeoArray(Point point) { - return new double[]{ - point.getX(), point.getY() - }; + return new double[] { point.getX(), point.getY() }; } -} \ No newline at end of file +} diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/DoubleIDRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/DoubleIDRepositoryTests.java index 94826bb83..a5f5b40fc 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/DoubleIDRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/DoubleIDRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import java.util.Arrays; +import java.util.Optional; import org.apache.commons.lang.math.RandomUtils; import org.junit.Before; @@ -34,8 +35,8 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author Rizwan Idrees * @author Mohsin Husen + * @author Mark Paluch */ - @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:/double-id-repository-test.xml") public class DoubleIDRepositoryTests { @@ -72,11 +73,11 @@ public class DoubleIDRepositoryTests { // when repository.save(Arrays.asList(sampleEntity1, sampleEntity2)); // then - DoubleIDEntity entity1FromElasticSearch = repository.findOne(documentId1); - assertThat(entity1FromElasticSearch, is(notNullValue())); + Optional entity1FromElasticSearch = repository.findOne(documentId1); + assertThat(entity1FromElasticSearch.isPresent(), is(true)); - DoubleIDEntity entity2FromElasticSearch = repository.findOne(documentId2); - assertThat(entity2FromElasticSearch, is(notNullValue())); + Optional entity2FromElasticSearch = repository.findOne(documentId2); + assertThat(entity2FromElasticSearch.isPresent(), is(true)); } @Test @@ -90,7 +91,7 @@ public class DoubleIDRepositoryTests { // when repository.save(sampleEntity); // then - DoubleIDEntity entityFromElasticSearch = repository.findOne(documentId); - assertThat(entityFromElasticSearch, is(notNullValue())); + Optional entityFromElasticSearch = repository.findOne(documentId); + assertThat(entityFromElasticSearch.isPresent(), is(true)); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformationCreatorImplTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformationCreatorImplTests.java index d4d69ef1b..35da48a13 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformationCreatorImplTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformationCreatorImplTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,10 @@ */ package org.springframework.data.elasticsearch.repository.support; +import static org.mockito.Mockito.*; + +import java.util.Optional; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -24,19 +28,17 @@ import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersiste import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.mapping.context.MappingContext; -import static org.mockito.Mockito.doReturn; - /** * @author Florian Hopf + * @author Mark Paluch */ @RunWith(MockitoJUnitRunner.class) public class ElasticsearchEntityInformationCreatorImplTests { - @Mock - private MappingContext, ElasticsearchPersistentProperty> mappingContext; - @Mock - private ElasticsearchPersistentEntity persistentEntity; - private ElasticsearchEntityInformationCreatorImpl entityInfoCreator; + @Mock MappingContext, ElasticsearchPersistentProperty> mappingContext; + @Mock ElasticsearchPersistentEntity persistentEntity; + + ElasticsearchEntityInformationCreatorImpl entityInfoCreator; @Before public void before() { @@ -50,9 +52,9 @@ public class ElasticsearchEntityInformationCreatorImplTests { @Test(expected = IllegalArgumentException.class) public void shouldThrowIllegalArgumentExceptionOnMissingIdAnnotation() { - doReturn(persistentEntity).when(mappingContext).getPersistentEntity(String.class); + doReturn(Optional.of(persistentEntity)).when(mappingContext).getPersistentEntity(String.class); doReturn(String.class).when(persistentEntity).getType(); - doReturn(null).when(persistentEntity).getIdProperty(); + doReturn(Optional.empty()).when(persistentEntity).getIdProperty(); entityInfoCreator.getEntityInformation(String.class); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactoryTests.java index 860fa4492..185c312ec 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,13 +29,14 @@ import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersiste import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.querydsl.QueryDslPredicateExecutor; +import org.springframework.data.querydsl.QuerydslPredicateExecutor; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; /** * @author Rizwan Idrees * @author Mohsin Husen + * @author Mark Paluch */ @RunWith(MockitoJUnitRunner.class) public class ElasticsearchRepositoryFactoryTests { @@ -56,7 +57,7 @@ public class ElasticsearchRepositoryFactoryTests { @Test(expected = IllegalArgumentException.class) public void shouldThrowExceptionGivenQueryDslRepository() { // given - RepositoryMetadata metadata = new DefaultRepositoryMetadata(QueryDslPredicateExecutor.class); + RepositoryMetadata metadata = new DefaultRepositoryMetadata(QuerydslPredicateExecutor.class); // when factory.getRepositoryBaseClass(metadata); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/IntegerIDRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/IntegerIDRepositoryTests.java index 5c8cb26a1..4c566ec8e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/IntegerIDRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/IntegerIDRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import java.util.Arrays; +import java.util.Optional; import org.apache.commons.lang.math.RandomUtils; import org.junit.Before; @@ -34,8 +35,8 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author Rizwan Idrees * @author Mohsin Husen + * @author Mark Paluch */ - @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:/integer-id-repository-test.xml") public class IntegerIDRepositoryTests { @@ -72,11 +73,11 @@ public class IntegerIDRepositoryTests { // when repository.save(Arrays.asList(sampleEntity1, sampleEntity2)); // then - IntegerIDEntity entity1FromElasticSearch = repository.findOne(documentId1); - assertThat(entity1FromElasticSearch, is(notNullValue())); + Optional entity1FromElasticSearch = repository.findOne(documentId1); + assertThat(entity1FromElasticSearch.isPresent(), is(true)); - IntegerIDEntity entity2FromElasticSearch = repository.findOne(documentId2); - assertThat(entity2FromElasticSearch, is(notNullValue())); + Optional entity2FromElasticSearch = repository.findOne(documentId2); + assertThat(entity2FromElasticSearch.isPresent(), is(true)); } @Test @@ -90,7 +91,7 @@ public class IntegerIDRepositoryTests { // when repository.save(sampleEntity); // then - IntegerIDEntity entityFromElasticSearch = repository.findOne(documentId); - assertThat(entityFromElasticSearch, is(notNullValue())); + Optional entityFromElasticSearch = repository.findOne(documentId); + assertThat(entityFromElasticSearch.isPresent(), is(true)); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepositoryTests.java index 608d59d78..11bd72994 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import static org.junit.Assert.*; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Optional; import com.google.common.collect.Lists; import org.junit.Before; @@ -43,8 +44,8 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author Rizwan Idrees * @author Mohsin Husen + * @author Mark Paluch */ - @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:/simple-repository-test.xml") public class SimpleElasticsearchRepositoryTests { @@ -81,11 +82,11 @@ public class SimpleElasticsearchRepositoryTests { // when repository.save(Arrays.asList(sampleEntity1, sampleEntity2)); // then - SampleEntity entity1FromElasticSearch = repository.findOne(documentId1); - assertThat(entity1FromElasticSearch, is(notNullValue())); + Optional entity1FromElasticSearch = repository.findOne(documentId1); + assertThat(entity1FromElasticSearch.isPresent(), is(true)); - SampleEntity entity2FromElasticSearch = repository.findOne(documentId2); - assertThat(entity2FromElasticSearch, is(notNullValue())); + Optional entity2FromElasticSearch = repository.findOne(documentId2); + assertThat(entity2FromElasticSearch.isPresent(), is(true)); } @Test @@ -99,8 +100,8 @@ public class SimpleElasticsearchRepositoryTests { // when repository.save(sampleEntity); // then - SampleEntity entityFromElasticSearch = repository.findOne(documentId); - assertThat(entityFromElasticSearch, is(notNullValue())); + Optional entityFromElasticSearch = repository.findOne(documentId); + assertThat(entityFromElasticSearch.isPresent(), is(true)); } @Test @@ -125,9 +126,9 @@ public class SimpleElasticsearchRepositoryTests { sampleEntity.setVersion(System.currentTimeMillis()); repository.save(sampleEntity); // when - SampleEntity entityFromElasticSearch = repository.findOne(documentId); + Optional entityFromElasticSearch = repository.findOne(documentId); // then - assertThat(entityFromElasticSearch, is(notNullValue())); + assertThat(entityFromElasticSearch.isPresent(), is(true)); assertThat(sampleEntity, is((equalTo(sampleEntity)))); } @@ -166,8 +167,8 @@ public class SimpleElasticsearchRepositoryTests { // when repository.delete(documentId); // then - SampleEntity entityFromElasticSearch = repository.findOne(documentId); - assertThat(entityFromElasticSearch, is(nullValue())); + Optional entityFromElasticSearch = repository.findOne(documentId); + assertThat(entityFromElasticSearch.isPresent(), is(false)); } @Test @@ -474,8 +475,8 @@ public class SimpleElasticsearchRepositoryTests { // when repository.delete(sampleEntities); // then - assertThat(repository.findOne(documentId1), is(nullValue())); - assertThat(repository.findOne(documentId2), is(nullValue())); + assertThat(repository.findOne(documentId1).isPresent(), is(false)); + assertThat(repository.findOne(documentId2).isPresent(), is(false)); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/UUIDElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/UUIDElasticsearchRepositoryTests.java index 8696b8f0a..d6affe697 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/UUIDElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/UUIDElasticsearchRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,8 +40,8 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; * @author Gad Akuka * @author Rizwan Idrees * @author Mohsin Husen + * @author Mark Paluch */ - @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:/simple-repository-test.xml") public class UUIDElasticsearchRepositoryTests { @@ -79,11 +79,11 @@ public class UUIDElasticsearchRepositoryTests { // when repository.save(Arrays.asList(sampleEntityUUIDKeyed1, sampleEntityUUIDKeyed2)); // then - SampleEntityUUIDKeyed entity1FromElasticSearch = repository.findOne(documentId1); - assertThat(entity1FromElasticSearch, is(notNullValue())); + Optional entity1FromElasticSearch = repository.findOne(documentId1); + assertThat(entity1FromElasticSearch.isPresent(), is(true)); - SampleEntityUUIDKeyed entity2FromElasticSearch = repository.findOne(documentId2); - assertThat(entity2FromElasticSearch, is(notNullValue())); + Optional entity2FromElasticSearch = repository.findOne(documentId2); + assertThat(entity2FromElasticSearch.isPresent(), is(true)); } @Test @@ -97,8 +97,8 @@ public class UUIDElasticsearchRepositoryTests { // when repository.save(sampleEntityUUIDKeyed); // then - SampleEntityUUIDKeyed entityFromElasticSearch = repository.findOne(documentId); - assertThat(entityFromElasticSearch, is(notNullValue())); + Optional entityFromElasticSearch = repository.findOne(documentId); + assertThat(entityFromElasticSearch.isPresent(), is(true)); } @Test @@ -111,9 +111,9 @@ public class UUIDElasticsearchRepositoryTests { sampleEntityUUIDKeyed.setVersion(System.currentTimeMillis()); repository.save(sampleEntityUUIDKeyed); // when - SampleEntityUUIDKeyed entityFromElasticSearch = repository.findOne(documentId); + Optional entityFromElasticSearch = repository.findOne(documentId); // then - assertThat(entityFromElasticSearch, is(notNullValue())); + assertThat(entityFromElasticSearch.isPresent(), is(true)); assertThat(sampleEntityUUIDKeyed, is((equalTo(sampleEntityUUIDKeyed)))); } @@ -152,8 +152,8 @@ public class UUIDElasticsearchRepositoryTests { // when repository.delete(documentId); // then - SampleEntityUUIDKeyed entityFromElasticSearch = repository.findOne(documentId); - assertThat(entityFromElasticSearch, is(nullValue())); + Optional entityFromElasticSearch = repository.findOne(documentId); + assertThat(entityFromElasticSearch.isPresent(), is(false)); } @Test @@ -445,8 +445,8 @@ public class UUIDElasticsearchRepositoryTests { // when repository.delete(sampleEntities); // then - assertThat(repository.findOne(documentId1), is(nullValue())); - assertThat(repository.findOne(documentId2), is(nullValue())); + assertThat(repository.findOne(documentId1).isPresent(), is(false)); + assertThat(repository.findOne(documentId2).isPresent(), is(false)); } @Test