diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 02558c058..96bf8a49e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -327,8 +327,13 @@ class RequestFactory { public MoreLikeThisQueryBuilder moreLikeThisQueryBuilder(MoreLikeThisQuery query, IndexCoordinates index) { MoreLikeThisQueryBuilder.Item item = new MoreLikeThisQueryBuilder.Item(index.getIndexName(), query.getId()); - MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = QueryBuilders - .moreLikeThisQuery(new MoreLikeThisQueryBuilder.Item[] { item }); + String[] fields = null; + if (query.getFields() != null) { + fields = query.getFields().toArray(new String[] {}); + } + + MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = QueryBuilders.moreLikeThisQuery(fields, null, + new MoreLikeThisQueryBuilder.Item[] { item }); if (query.getMinTermFreq() != null) { moreLikeThisQueryBuilder.minTermFreq(query.getMinTermFreq()); @@ -361,6 +366,7 @@ class RequestFactory { if (query.getBoostTerms() != null) { moreLikeThisQueryBuilder.boostTerms(query.getBoostTerms()); } + return moreLikeThisQueryBuilder; } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchCrudRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchCrudRepository.java index 9e29de536..2730a6afb 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchCrudRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchCrudRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. @@ -25,8 +25,9 @@ import org.springframework.data.repository.PagingAndSortingRepository; * @author Mohsin Husen * @author Oliver Gierke * @author Sascha Woo + * @author Peter-Josef Meisch + * @deprecated since 4.0, use {@link ElasticsearchRepository} instead */ +@Deprecated @NoRepositoryBean -public interface ElasticsearchCrudRepository extends PagingAndSortingRepository { - -} +public interface ElasticsearchCrudRepository extends PagingAndSortingRepository {} diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java index 9e7ad0bd8..8d63042d3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java @@ -18,8 +18,11 @@ package org.springframework.data.elasticsearch.repository; import org.elasticsearch.index.query.QueryBuilder; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.repository.NoRepositoryBean; +import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.lang.Nullable; /** * @param @@ -31,9 +34,15 @@ import org.springframework.data.repository.NoRepositoryBean; * @author Peter-Josef Meisch */ @NoRepositoryBean -public interface ElasticsearchRepository extends ElasticsearchCrudRepository { +public interface ElasticsearchRepository extends PagingAndSortingRepository { - S index(S entity); + /** + * @deprecated since 4.0, use {@link #save(Object)} instead + */ + @Deprecated + default S index(S entity) { + return save(entity); + } /** * This method is intended to be used when many single inserts must be made that cannot be aggregated to be inserted @@ -42,15 +51,38 @@ public interface ElasticsearchRepository extends ElasticsearchCrudReposit */ S indexWithoutRefresh(S entity); + /** + * @deprecated since 4.0, use standard repository method naming or @{@link Query} annotated methods, or + * {@link org.springframework.data.elasticsearch.core.ElasticsearchOperations}. + */ Iterable search(QueryBuilder query); + /** + * @deprecated since 4.0, use standard repository method naming or @{@link Query} annotated methods, or + * {@link org.springframework.data.elasticsearch.core.ElasticsearchOperations}. + */ Page search(QueryBuilder query, Pageable pageable); + /** + * @deprecated since 4.0, use standard repository method naming or @{@link Query} annotated methods, or + * {@link org.springframework.data.elasticsearch.core.ElasticsearchOperations}. + */ Page search(Query searchQuery); - Page searchSimilar(T entity, String[] fields, Pageable pageable); + /** + * Search for similar entities using a morelikethis query + * + * @param entity the entity for which similar documents should be searched, must not be {@literal null} + * @param fields + * @param pageable , must not be {@literal null} + * @return + */ + Page searchSimilar(T entity, @Nullable String[] fields, Pageable pageable); + /** + * @deprecated since 4.0, use {@link IndexOperations#refresh(Class)} instead. Repository methods should call refresh + * in their implementation. + */ + @Deprecated void refresh(); - - Class getEntityClass(); } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/config/ElasticsearchRepositoryConfigExtension.java b/src/main/java/org/springframework/data/elasticsearch/repository/config/ElasticsearchRepositoryConfigExtension.java index b50543b86..a03d68705 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/config/ElasticsearchRepositoryConfigExtension.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/config/ElasticsearchRepositoryConfigExtension.java @@ -23,7 +23,6 @@ import java.util.Collections; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.data.elasticsearch.annotations.Document; -import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.elasticsearch.repository.support.ElasticsearchRepositoryFactoryBean; import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource; @@ -99,7 +98,7 @@ public class ElasticsearchRepositoryConfigExtension extends RepositoryConfigurat */ @Override protected Collection> getIdentifyingTypes() { - return Arrays.asList(ElasticsearchRepository.class, ElasticsearchCrudRepository.class); + return Arrays.asList(ElasticsearchRepository.class, ElasticsearchRepository.class); } /* diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/package-info.java new file mode 100644 index 000000000..9d9e57ab2 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/repository/package-info.java @@ -0,0 +1,5 @@ +/** + * infrastructure to define the Elasticsearch mapping for an index. + */ +@org.springframework.lang.NonNullApi +package org.springframework.data.elasticsearch.repository; diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java index 546b6e49d..b6be9d570 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java @@ -76,6 +76,7 @@ public class ElasticsearchPartQuery extends AbstractElasticsearchRepositoryQuery if (tree.isDelete()) { result = countOrGetDocumentsForDelete(query, accessor); elasticsearchOperations.delete(query, clazz, index); + elasticsearchOperations.getIndexOperations().refresh(index); } else if (queryMethod.isPageQuery()) { query.setPageable(accessor.getPageable()); SearchHits searchHits = elasticsearchOperations.search(query, clazz, index); 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 5977febef..87f707fda 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 @@ -52,6 +52,7 @@ import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilde import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.util.Streamable; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -132,11 +133,12 @@ public abstract class AbstractElasticsearchRepository implements Elastics int itemCount = (int) this.count(); if (itemCount == 0) { - return new PageImpl<>(Collections. emptyList()); + return new PageImpl<>(Collections.emptyList()); } return this.findAll(PageRequest.of(0, Math.max(1, itemCount))); } + @SuppressWarnings("unchecked") @Override public Page findAll(Pageable pageable) { NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withPageable(pageable).build(); @@ -145,12 +147,13 @@ public abstract class AbstractElasticsearchRepository implements Elastics return (Page) SearchHitSupport.unwrapSearchHits(page); } + @SuppressWarnings("unchecked") @Override public Iterable findAll(Sort sort) { int itemCount = (int) this.count(); if (itemCount == 0) { - return new PageImpl<>(Collections. emptyList()); + return new PageImpl<>(Collections.emptyList()); } NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, itemCount, sort)).build(); @@ -185,11 +188,6 @@ public abstract class AbstractElasticsearchRepository implements Elastics return Streamable.of(saveAll(entities)).stream().collect(Collectors.toList()); } - @Override - public S index(S entity) { - return save(entity); - } - @Override public S indexWithoutRefresh(S entity) { Assert.notNull(entity, "Cannot save 'null' entity."); @@ -216,13 +214,14 @@ public abstract class AbstractElasticsearchRepository implements Elastics return findById(id).isPresent(); } + @SuppressWarnings("unchecked") @Override public Iterable search(QueryBuilder query) { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).build(); int count = (int) operations.count(searchQuery, getEntityClass(), getIndexCoordinates()); if (count == 0) { - return new PageImpl<>(Collections. emptyList()); + return new PageImpl<>(Collections.emptyList()); } searchQuery.setPageable(PageRequest.of(0, count)); SearchHits searchHits = operations.search(searchQuery, getEntityClass(), getIndexCoordinates()); @@ -230,6 +229,7 @@ public abstract class AbstractElasticsearchRepository implements Elastics return (Page) SearchHitSupport.unwrapSearchHits(page); } + @SuppressWarnings("unchecked") @Override public Page search(QueryBuilder query, Pageable pageable) { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).withPageable(pageable).build(); @@ -238,6 +238,7 @@ public abstract class AbstractElasticsearchRepository implements Elastics return (Page) SearchHitSupport.unwrapSearchHits(page); } + @SuppressWarnings("unchecked") @Override public Page search(Query query) { SearchHits searchHits = operations.search(query, getEntityClass(), getIndexCoordinates()); @@ -245,6 +246,7 @@ public abstract class AbstractElasticsearchRepository implements Elastics return (Page) SearchHitSupport.unwrapSearchHits(page); } + @SuppressWarnings("unchecked") @Override public Page searchSimilar(T entity, String[] fields, Pageable pageable) { Assert.notNull(entity, "Cannot search similar records for 'null'."); @@ -264,24 +266,39 @@ public abstract class AbstractElasticsearchRepository implements Elastics @Override public void deleteById(ID id) { + Assert.notNull(id, "Cannot delete entity with id 'null'."); + IndexCoordinates indexCoordinates = getIndexCoordinates(); - operations.delete(stringIdRepresentation(id), indexCoordinates); + doDelete(id, indexCoordinates); indexOperations.refresh(indexCoordinates); } @Override public void delete(T entity) { + Assert.notNull(entity, "Cannot delete 'null' entity."); - deleteById(extractIdFromBean(entity)); - indexOperations.refresh(getIndexCoordinates()); + + IndexCoordinates indexCoordinates = getIndexCoordinates(); + doDelete(extractIdFromBean(entity), indexCoordinates); + indexOperations.refresh(indexCoordinates); } @Override public void deleteAll(Iterable entities) { + Assert.notNull(entities, "Cannot delete 'null' list."); + + IndexCoordinates indexCoordinates = getIndexCoordinates(); for (T entity : entities) { - delete(entity); + doDelete(extractIdFromBean(entity), indexCoordinates); + } + indexOperations.refresh(indexCoordinates); + } + + private void doDelete(@Nullable ID id, IndexCoordinates indexCoordinates) { + if (id != null) { + operations.delete(stringIdRepresentation(id), indexCoordinates); } } @@ -328,8 +345,7 @@ public abstract class AbstractElasticsearchRepository implements Elastics return resolveReturnedClassFromGenericType(clazz.getSuperclass()); } - @Override - public Class getEntityClass() { + protected Class getEntityClass() { if (!isEntityClassSet()) { try { @@ -350,6 +366,7 @@ public abstract class AbstractElasticsearchRepository implements Elastics this.entityClass = entityClass; } + @Nullable protected ID extractIdFromBean(T entity) { return entityInformation.getId(entity); } @@ -364,7 +381,7 @@ public abstract class AbstractElasticsearchRepository implements Elastics return stringIds; } - protected abstract String stringIdRepresentation(ID id); + protected abstract String stringIdRepresentation(@Nullable ID id); private Long extractVersionFromBean(T entity) { return entityInformation.getVersion(entity); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/package-info.java new file mode 100644 index 000000000..3c33bb8e0 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/package-info.java @@ -0,0 +1,5 @@ +/** + * infrastructure to define the Elasticsearch mapping for an index. + */ +@org.springframework.lang.NonNullApi +package org.springframework.data.elasticsearch.repository.support; diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java index ab972d8a0..649f09c46 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java @@ -39,7 +39,7 @@ import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; -import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; @@ -229,6 +229,6 @@ public class DynamicSettingAndMappingEntityRepositoryTests { * @author Mohsin Husen */ public interface DynamicSettingAndMappingEntityRepository - extends ElasticsearchCrudRepository {} + extends ElasticsearchRepository {} } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java index aee8fe076..c673f35c3 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java @@ -32,7 +32,7 @@ import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; -import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; @@ -57,6 +57,7 @@ public class FieldDynamicMappingEntityRepositoryTests { @Autowired private ElasticsearchOperations operations; private IndexOperations indexOperations; + @BeforeEach public void before() { indexOperations = operations.getIndexOperations(); @@ -129,6 +130,6 @@ public class FieldDynamicMappingEntityRepositoryTests { * @author Ted Liang */ public interface FieldDynamicMappingEntityRepository - extends ElasticsearchCrudRepository {} + extends ElasticsearchRepository {} } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java index cfd9d7cbe..7950b2f2d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java @@ -37,7 +37,7 @@ import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; -import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; @@ -72,6 +72,7 @@ public class SynonymRepositoryTests { void after() { indexOperations.deleteIndex(SynonymEntity.class); } + @Test public void shouldDo() { @@ -112,5 +113,5 @@ public class SynonymRepositoryTests { * * @author Artur Konczak */ - interface SynonymRepository extends ElasticsearchCrudRepository {} + interface SynonymRepository extends ElasticsearchRepository {} } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java index 1a9673c6f..fc73c16b3 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java @@ -389,7 +389,6 @@ public class UUIDElasticsearchRepositoryTests { // when List result = repository.deleteByAvailable(true); - repository.refresh(); // then assertThat(result).hasSize(2); @@ -423,7 +422,6 @@ public class UUIDElasticsearchRepositoryTests { // when List result = repository.deleteByMessage("hello world 3"); - repository.refresh(); // then assertThat(result).hasSize(1); @@ -457,7 +455,6 @@ public class UUIDElasticsearchRepositoryTests { // when repository.deleteByType("article"); - repository.refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); @@ -478,7 +475,6 @@ public class UUIDElasticsearchRepositoryTests { // when repository.delete(sampleEntityUUIDKeyed); - repository.refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId.toString())) @@ -601,8 +597,7 @@ public class UUIDElasticsearchRepositoryTests { @AllArgsConstructor @Builder @Data - @Document(indexName = "test-index-uuid-keyed", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-uuid-keyed", replicas = 0, refreshInterval = "-1") static class SampleEntityUUIDKeyed { @Id private UUID id; diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java index 080fa30c8..de6eb3558 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java @@ -148,9 +148,7 @@ public class SimpleElasticsearchRepositoryTests { sampleEntity.setVersion(System.currentTimeMillis()); // when - assertThatThrownBy(() -> { - repository.save(sampleEntity); - }).isInstanceOf(ActionRequestValidationException.class); + assertThatThrownBy(() -> repository.save(sampleEntity)).isInstanceOf(ActionRequestValidationException.class); } @Test @@ -385,7 +383,6 @@ public class SimpleElasticsearchRepositoryTests { // when long result = repository.deleteSampleEntityById(documentId); - repository.refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); @@ -422,7 +419,6 @@ public class SimpleElasticsearchRepositoryTests { // when List result = repository.deleteByAvailable(true); - repository.refresh(); // then assertThat(result).hasSize(2); @@ -456,7 +452,6 @@ public class SimpleElasticsearchRepositoryTests { // when List result = repository.deleteByMessage("hello world 3"); - repository.refresh(); // then assertThat(result).hasSize(1); @@ -490,7 +485,6 @@ public class SimpleElasticsearchRepositoryTests { // when repository.deleteByType("article"); - repository.refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); @@ -581,7 +575,7 @@ public class SimpleElasticsearchRepositoryTests { sampleEntity.setMessage("some message"); // when - repository.index(sampleEntity); + repository.save(sampleEntity); // then Page entities = repository.search(termQuery("id", documentId), PageRequest.of(0, 50)); @@ -707,8 +701,7 @@ public class SimpleElasticsearchRepositoryTests { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-sample-simple-repository", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-sample-simple-repository", replicas = 0, refreshInterval = "-1") static class SampleEntity { @Id private String id;