|
15 | 15 | */
|
16 | 16 | package org.springframework.data.elasticsearch.repository.support;
|
17 | 17 |
|
18 |
| -import static org.elasticsearch.index.query.QueryBuilders.*; |
19 |
| - |
20 |
| -import java.lang.reflect.ParameterizedType; |
21 |
| -import java.lang.reflect.Type; |
22 |
| -import java.util.ArrayList; |
23 |
| -import java.util.Collections; |
24 |
| -import java.util.List; |
25 |
| -import java.util.Optional; |
26 |
| -import java.util.stream.Collectors; |
27 |
| - |
28 |
| -import org.elasticsearch.index.query.IdsQueryBuilder; |
29 |
| -import org.elasticsearch.index.query.QueryBuilder; |
30 |
| -import org.slf4j.Logger; |
31 |
| -import org.slf4j.LoggerFactory; |
32 |
| -import org.springframework.dao.InvalidDataAccessApiUsageException; |
33 |
| -import org.springframework.data.domain.Page; |
34 |
| -import org.springframework.data.domain.PageImpl; |
35 |
| -import org.springframework.data.domain.PageRequest; |
36 |
| -import org.springframework.data.domain.Pageable; |
37 |
| -import org.springframework.data.domain.Sort; |
38 | 18 | import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
|
39 |
| -import org.springframework.data.elasticsearch.core.IndexOperations; |
40 |
| -import org.springframework.data.elasticsearch.core.SearchHit; |
41 |
| -import org.springframework.data.elasticsearch.core.SearchHitSupport; |
42 |
| -import org.springframework.data.elasticsearch.core.SearchHits; |
43 |
| -import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; |
44 |
| -import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; |
45 |
| -import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; |
46 |
| -import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; |
47 |
| -import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; |
48 |
| -import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; |
49 |
| -import org.springframework.data.elasticsearch.core.query.Query; |
50 |
| -import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; |
51 |
| -import org.springframework.data.util.Streamable; |
52 |
| -import org.springframework.lang.Nullable; |
53 |
| -import org.springframework.util.Assert; |
54 | 19 |
|
55 | 20 | /**
|
56 | 21 | * Elasticsearch specific repository implementation. Likely to be used as target within
|
|
59 | 24 | * @author Rizwan Idrees
|
60 | 25 | * @author Mohsin Husen
|
61 | 26 | * @author Ryan Henszey
|
62 |
| - * @author Kevin Leturc |
63 |
| - * @author Mark Paluch |
64 |
| - * @author Christoph Strobl |
65 |
| - * @author Michael Wirth |
66 | 27 | * @author Sascha Woo
|
67 |
| - * @author Murali Chevuri |
68 | 28 | * @author Peter-Josef Meisch
|
69 |
| - * @author Aleksei Arsenev |
| 29 | + * @deprecated since 4.1, derive from {@link SimpleElasticsearchRepository} instead |
70 | 30 | */
|
71 |
| -public abstract class AbstractElasticsearchRepository<T, ID> implements ElasticsearchRepository<T, ID> { |
72 |
| - |
73 |
| - static final Logger LOGGER = LoggerFactory.getLogger(AbstractElasticsearchRepository.class); |
74 |
| - |
75 |
| - protected ElasticsearchOperations operations; |
76 |
| - protected IndexOperations indexOperations; |
77 |
| - |
78 |
| - protected Class<T> entityClass; |
79 |
| - protected @Nullable ElasticsearchEntityInformation<T, ID> entityInformation; |
| 31 | +@Deprecated |
| 32 | +public abstract class AbstractElasticsearchRepository<T, ID> extends SimpleElasticsearchRepository<T, ID> { |
80 | 33 |
|
81 | 34 | public AbstractElasticsearchRepository(ElasticsearchEntityInformation<T, ID> metadata,
|
82 |
| - ElasticsearchOperations operations) { |
83 |
| - this.operations = operations; |
84 |
| - |
85 |
| - Assert.notNull(metadata, "ElasticsearchEntityInformation must not be null!"); |
86 |
| - |
87 |
| - this.entityInformation = metadata; |
88 |
| - this.entityClass = this.entityInformation.getJavaType(); |
89 |
| - this.indexOperations = operations.indexOps(this.entityClass); |
90 |
| - try { |
91 |
| - if (createIndexAndMapping() && !indexOperations.exists()) { |
92 |
| - createIndex(); |
93 |
| - putMapping(); |
94 |
| - } |
95 |
| - } catch (Exception exception) { |
96 |
| - LOGGER.warn("Cannot create index: {}", exception.getMessage()); |
97 |
| - } |
98 |
| - } |
99 |
| - |
100 |
| - private void createIndex() { |
101 |
| - indexOperations.create(); |
102 |
| - } |
103 |
| - |
104 |
| - private void putMapping() { |
105 |
| - indexOperations.putMapping(entityClass); |
106 |
| - } |
107 |
| - |
108 |
| - private boolean createIndexAndMapping() { |
109 |
| - |
110 |
| - final ElasticsearchPersistentEntity<?> entity = operations.getElasticsearchConverter().getMappingContext() |
111 |
| - .getRequiredPersistentEntity(getEntityClass()); |
112 |
| - return entity.isCreateIndexAndMapping(); |
113 |
| - } |
114 |
| - |
115 |
| - @Override |
116 |
| - public Optional<T> findById(ID id) { |
117 |
| - return Optional.ofNullable(operations.get(stringIdRepresentation(id), getEntityClass(), getIndexCoordinates())); |
118 |
| - } |
119 |
| - |
120 |
| - @Override |
121 |
| - public Iterable<T> findAll() { |
122 |
| - int itemCount = (int) this.count(); |
123 |
| - |
124 |
| - if (itemCount == 0) { |
125 |
| - return new PageImpl<>(Collections.emptyList()); |
126 |
| - } |
127 |
| - return this.findAll(PageRequest.of(0, Math.max(1, itemCount))); |
128 |
| - } |
129 |
| - |
130 |
| - @SuppressWarnings("unchecked") |
131 |
| - @Override |
132 |
| - public Page<T> findAll(Pageable pageable) { |
133 |
| - NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withPageable(pageable).build(); |
134 |
| - SearchHits<T> searchHits = operations.search(query, getEntityClass(), getIndexCoordinates()); |
135 |
| - AggregatedPage<SearchHit<T>> page = SearchHitSupport.page(searchHits, query.getPageable()); |
136 |
| - return (Page<T>) SearchHitSupport.unwrapSearchHits(page); |
137 |
| - } |
138 |
| - |
139 |
| - @SuppressWarnings("unchecked") |
140 |
| - @Override |
141 |
| - public Iterable<T> findAll(Sort sort) { |
142 |
| - int itemCount = (int) this.count(); |
143 |
| - |
144 |
| - if (itemCount == 0) { |
145 |
| - return new PageImpl<>(Collections.emptyList()); |
146 |
| - } |
147 |
| - NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) |
148 |
| - .withPageable(PageRequest.of(0, itemCount, sort)).build(); |
149 |
| - List<SearchHit<T>> searchHitList = operations.search(query, getEntityClass(), getIndexCoordinates()) |
150 |
| - .getSearchHits(); |
151 |
| - return (List<T>) SearchHitSupport.unwrapSearchHits(searchHitList); |
152 |
| - } |
153 |
| - |
154 |
| - @Override |
155 |
| - public Iterable<T> findAllById(Iterable<ID> ids) { |
156 |
| - Assert.notNull(ids, "ids can't be null."); |
157 |
| - NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(stringIdsRepresentation(ids)).build(); |
158 |
| - return operations.multiGet(query, getEntityClass(), getIndexCoordinates()); |
159 |
| - } |
160 |
| - |
161 |
| - @Override |
162 |
| - public long count() { |
163 |
| - NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); |
164 |
| - return operations.count(query, getEntityClass(), getIndexCoordinates()); |
165 |
| - } |
166 |
| - |
167 |
| - @Override |
168 |
| - public <S extends T> S save(S entity) { |
169 |
| - |
170 |
| - Assert.notNull(entity, "Cannot save 'null' entity."); |
171 |
| - |
172 |
| - operations.save(entity, getIndexCoordinates()); |
173 |
| - operations.indexOps(entity.getClass()).refresh(); |
174 |
| - return entity; |
175 |
| - } |
176 |
| - |
177 |
| - public <S extends T> List<S> save(List<S> entities) { |
178 |
| - |
179 |
| - Assert.notNull(entities, "Cannot insert 'null' as a List."); |
180 |
| - |
181 |
| - return Streamable.of(saveAll(entities)).stream().collect(Collectors.toList()); |
182 |
| - } |
183 |
| - |
184 |
| - @Override |
185 |
| - @Deprecated |
186 |
| - public <S extends T> S indexWithoutRefresh(S entity) { |
187 |
| - Assert.notNull(entity, "Cannot save 'null' entity."); |
188 |
| - operations.save(entity); |
189 |
| - return entity; |
190 |
| - } |
191 |
| - |
192 |
| - @Override |
193 |
| - public <S extends T> Iterable<S> saveAll(Iterable<S> entities) { |
194 |
| - |
195 |
| - Assert.notNull(entities, "Cannot insert 'null' as a List."); |
196 |
| - |
197 |
| - IndexCoordinates indexCoordinates = getIndexCoordinates(); |
198 |
| - operations.save(entities, indexCoordinates); |
199 |
| - operations.indexOps(indexCoordinates).refresh(); |
200 |
| - |
201 |
| - return entities; |
202 |
| - } |
203 |
| - |
204 |
| - @Override |
205 |
| - public boolean existsById(ID id) { |
206 |
| - return operations.exists(stringIdRepresentation(id), getIndexCoordinates()); |
207 |
| - } |
208 |
| - |
209 |
| - @SuppressWarnings("unchecked") |
210 |
| - @Override |
211 |
| - public Iterable<T> search(QueryBuilder query) { |
212 |
| - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).build(); |
213 |
| - int count = (int) operations.count(searchQuery, getEntityClass(), getIndexCoordinates()); |
214 |
| - |
215 |
| - if (count == 0) { |
216 |
| - return new PageImpl<>(Collections.emptyList()); |
217 |
| - } |
218 |
| - searchQuery.setPageable(PageRequest.of(0, count)); |
219 |
| - SearchHits<T> searchHits = operations.search(searchQuery, getEntityClass(), getIndexCoordinates()); |
220 |
| - AggregatedPage<SearchHit<T>> page = SearchHitSupport.page(searchHits, searchQuery.getPageable()); |
221 |
| - return (Page<T>) SearchHitSupport.unwrapSearchHits(page); |
222 |
| - } |
223 |
| - |
224 |
| - @SuppressWarnings("unchecked") |
225 |
| - @Override |
226 |
| - public Page<T> search(QueryBuilder query, Pageable pageable) { |
227 |
| - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).withPageable(pageable).build(); |
228 |
| - SearchHits<T> searchHits = operations.search(searchQuery, getEntityClass(), getIndexCoordinates()); |
229 |
| - AggregatedPage<SearchHit<T>> page = SearchHitSupport.page(searchHits, searchQuery.getPageable()); |
230 |
| - return (Page<T>) SearchHitSupport.unwrapSearchHits(page); |
231 |
| - } |
232 |
| - |
233 |
| - @SuppressWarnings("unchecked") |
234 |
| - @Override |
235 |
| - public Page<T> search(Query query) { |
236 |
| - SearchHits<T> searchHits = operations.search(query, getEntityClass(), getIndexCoordinates()); |
237 |
| - AggregatedPage<SearchHit<T>> page = SearchHitSupport.page(searchHits, query.getPageable()); |
238 |
| - return (Page<T>) SearchHitSupport.unwrapSearchHits(page); |
239 |
| - } |
240 |
| - |
241 |
| - @SuppressWarnings("unchecked") |
242 |
| - @Override |
243 |
| - public Page<T> searchSimilar(T entity, @Nullable String[] fields, Pageable pageable) { |
244 |
| - |
245 |
| - Assert.notNull(entity, "Cannot search similar records for 'null'."); |
246 |
| - Assert.notNull(pageable, "'pageable' cannot be 'null'"); |
247 |
| - |
248 |
| - MoreLikeThisQuery query = new MoreLikeThisQuery(); |
249 |
| - query.setId(stringIdRepresentation(extractIdFromBean(entity))); |
250 |
| - query.setPageable(pageable); |
251 |
| - |
252 |
| - if (fields != null) { |
253 |
| - query.addFields(fields); |
254 |
| - } |
255 |
| - |
256 |
| - SearchHits<T> searchHits = operations.search(query, getEntityClass(), getIndexCoordinates()); |
257 |
| - AggregatedPage<SearchHit<T>> page = SearchHitSupport.page(searchHits, pageable); |
258 |
| - return (Page<T>) SearchHitSupport.unwrapSearchHits(page); |
259 |
| - } |
260 |
| - |
261 |
| - @Override |
262 |
| - public void deleteById(ID id) { |
263 |
| - |
264 |
| - Assert.notNull(id, "Cannot delete entity with id 'null'."); |
265 |
| - |
266 |
| - IndexCoordinates indexCoordinates = getIndexCoordinates(); |
267 |
| - doDelete(id, indexCoordinates); |
268 |
| - indexOperations.refresh(); |
269 |
| - } |
270 |
| - |
271 |
| - @Override |
272 |
| - public void delete(T entity) { |
273 |
| - |
274 |
| - Assert.notNull(entity, "Cannot delete 'null' entity."); |
275 |
| - |
276 |
| - IndexCoordinates indexCoordinates = getIndexCoordinates(); |
277 |
| - doDelete(extractIdFromBean(entity), indexCoordinates); |
278 |
| - indexOperations.refresh(); |
279 |
| - } |
280 |
| - |
281 |
| - @Override |
282 |
| - public void deleteAll(Iterable<? extends T> entities) { |
283 |
| - |
284 |
| - Assert.notNull(entities, "Cannot delete 'null' list."); |
285 |
| - |
286 |
| - IndexCoordinates indexCoordinates = getIndexCoordinates(); |
287 |
| - IdsQueryBuilder idsQueryBuilder = idsQuery(); |
288 |
| - for (T entity : entities) { |
289 |
| - ID id = extractIdFromBean(entity); |
290 |
| - if (id != null) { |
291 |
| - idsQueryBuilder.addIds(stringIdRepresentation(id)); |
292 |
| - } |
293 |
| - } |
294 |
| - |
295 |
| - if (idsQueryBuilder.ids().isEmpty()) { |
296 |
| - return; |
297 |
| - } |
298 |
| - |
299 |
| - Query query = new NativeSearchQueryBuilder().withQuery(idsQueryBuilder).build(); |
300 |
| - |
301 |
| - operations.delete(query, getEntityClass(), indexCoordinates); |
302 |
| - indexOperations.refresh(); |
303 |
| - } |
304 |
| - |
305 |
| - private void doDelete(@Nullable ID id, IndexCoordinates indexCoordinates) { |
306 |
| - if (id != null) { |
307 |
| - operations.delete(stringIdRepresentation(id), indexCoordinates); |
308 |
| - } |
309 |
| - } |
310 |
| - |
311 |
| - @Override |
312 |
| - public void deleteAll() { |
313 |
| - IndexCoordinates indexCoordinates = getIndexCoordinates(); |
314 |
| - Query query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); |
315 |
| - |
316 |
| - operations.delete(query, getEntityClass(), indexCoordinates); |
317 |
| - indexOperations.refresh(); |
318 |
| - } |
319 |
| - |
320 |
| - @Override |
321 |
| - public void refresh() { |
322 |
| - indexOperations.refresh(); |
323 |
| - } |
324 |
| - |
325 |
| - @SuppressWarnings("unchecked") |
326 |
| - private Class<T> resolveReturnedClassFromGenericType() { |
327 |
| - ParameterizedType parameterizedType = resolveReturnedClassFromGenericType(getClass()); |
328 |
| - return (Class<T>) parameterizedType.getActualTypeArguments()[0]; |
329 |
| - } |
330 |
| - |
331 |
| - private ParameterizedType resolveReturnedClassFromGenericType(Class<?> clazz) { |
332 |
| - Object genericSuperclass = clazz.getGenericSuperclass(); |
333 |
| - |
334 |
| - if (genericSuperclass instanceof ParameterizedType) { |
335 |
| - ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass; |
336 |
| - Type rawtype = parameterizedType.getRawType(); |
337 |
| - if (SimpleElasticsearchRepository.class.equals(rawtype)) { |
338 |
| - return parameterizedType; |
339 |
| - } |
340 |
| - } |
341 |
| - |
342 |
| - return resolveReturnedClassFromGenericType(clazz.getSuperclass()); |
343 |
| - } |
344 |
| - |
345 |
| - protected Class<T> getEntityClass() { |
346 |
| - |
347 |
| - if (!isEntityClassSet()) { |
348 |
| - try { |
349 |
| - this.entityClass = resolveReturnedClassFromGenericType(); |
350 |
| - } catch (Exception e) { |
351 |
| - throw new InvalidDataAccessApiUsageException("Unable to resolve EntityClass. Please use according setter!", e); |
352 |
| - } |
353 |
| - } |
354 |
| - return entityClass; |
355 |
| - } |
356 |
| - |
357 |
| - private boolean isEntityClassSet() { |
358 |
| - return entityClass != null; |
359 |
| - } |
360 |
| - |
361 |
| - @Nullable |
362 |
| - protected ID extractIdFromBean(T entity) { |
363 |
| - return entityInformation.getId(entity); |
364 |
| - } |
365 |
| - |
366 |
| - private List<String> stringIdsRepresentation(Iterable<ID> ids) { |
367 |
| - Assert.notNull(ids, "ids can't be null."); |
368 |
| - List<String> stringIds = new ArrayList<>(); |
369 |
| - for (ID id : ids) { |
370 |
| - stringIds.add(stringIdRepresentation(id)); |
371 |
| - } |
372 |
| - |
373 |
| - return stringIds; |
374 |
| - } |
375 |
| - |
376 |
| - protected abstract @Nullable String stringIdRepresentation(@Nullable ID id); |
377 |
| - |
378 |
| - private IndexCoordinates getIndexCoordinates() { |
379 |
| - return operations.getIndexCoordinatesFor(getEntityClass()); |
| 35 | + ElasticsearchOperations elasticsearchOperations) { |
| 36 | + super(metadata, elasticsearchOperations); |
380 | 37 | }
|
381 | 38 | }
|
0 commit comments