mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-06-29 07:12:26 +00:00
Fix handling of @ID property in Java records.
Original Pull Request #2757 Closes #2756
This commit is contained in:
parent
9abcacb2e9
commit
2f6fae632b
@ -224,8 +224,16 @@ public class ElasticsearchTemplate extends AbstractElasticsearchTemplate {
|
|||||||
Object queryObject = query.getObject();
|
Object queryObject = query.getObject();
|
||||||
|
|
||||||
if (queryObject != null) {
|
if (queryObject != null) {
|
||||||
query.setObject(updateIndexedObject(queryObject, new IndexedObjectInformation(indexResponse.id(),
|
query.setObject(entityOperations.updateIndexedObject(
|
||||||
indexResponse.index(), indexResponse.seqNo(), indexResponse.primaryTerm(), indexResponse.version())));
|
queryObject,
|
||||||
|
new IndexedObjectInformation(
|
||||||
|
indexResponse.id(),
|
||||||
|
indexResponse.index(),
|
||||||
|
indexResponse.seqNo(),
|
||||||
|
indexResponse.primaryTerm(),
|
||||||
|
indexResponse.version()),
|
||||||
|
elasticsearchConverter,
|
||||||
|
routingResolver));
|
||||||
}
|
}
|
||||||
|
|
||||||
return indexResponse.id();
|
return indexResponse.id();
|
||||||
|
@ -141,13 +141,16 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
|
|||||||
.flatMap(indexAndResponse -> {
|
.flatMap(indexAndResponse -> {
|
||||||
T savedEntity = entities.entityAt(indexAndResponse.getT1());
|
T savedEntity = entities.entityAt(indexAndResponse.getT1());
|
||||||
BulkResponseItem response = indexAndResponse.getT2();
|
BulkResponseItem response = indexAndResponse.getT2();
|
||||||
updateIndexedObject(savedEntity, new IndexedObjectInformation( //
|
var updatedEntity = entityOperations.updateIndexedObject(
|
||||||
|
savedEntity, new IndexedObjectInformation( //
|
||||||
response.id(), //
|
response.id(), //
|
||||||
response.index(), //
|
response.index(), //
|
||||||
response.seqNo(), //
|
response.seqNo(), //
|
||||||
response.primaryTerm(), //
|
response.primaryTerm(), //
|
||||||
response.version()));
|
response.version()),
|
||||||
return maybeCallbackAfterSave(savedEntity, index);
|
converter,
|
||||||
|
routingResolver);
|
||||||
|
return maybeCallbackAfterSave(updatedEntity, index);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,6 @@ import org.springframework.data.elasticsearch.core.routing.DefaultRoutingResolve
|
|||||||
import org.springframework.data.elasticsearch.core.routing.RoutingResolver;
|
import org.springframework.data.elasticsearch.core.routing.RoutingResolver;
|
||||||
import org.springframework.data.elasticsearch.core.script.Script;
|
import org.springframework.data.elasticsearch.core.script.Script;
|
||||||
import org.springframework.data.elasticsearch.support.VersionInfo;
|
import org.springframework.data.elasticsearch.support.VersionInfo;
|
||||||
import org.springframework.data.mapping.PersistentPropertyAccessor;
|
|
||||||
import org.springframework.data.mapping.callback.EntityCallbacks;
|
import org.springframework.data.mapping.callback.EntityCallbacks;
|
||||||
import org.springframework.data.mapping.context.MappingContext;
|
import org.springframework.data.mapping.context.MappingContext;
|
||||||
import org.springframework.data.util.Streamable;
|
import org.springframework.data.util.Streamable;
|
||||||
@ -240,7 +239,11 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
|
|||||||
// noinspection unchecked
|
// noinspection unchecked
|
||||||
return indexQueries.stream() //
|
return indexQueries.stream() //
|
||||||
.map(IndexQuery::getObject) //
|
.map(IndexQuery::getObject) //
|
||||||
.map(entity -> (T) updateIndexedObject(entity, iterator.next())) //
|
.map(entity -> (T) entityOperations.updateIndexedObject(
|
||||||
|
entity,
|
||||||
|
iterator.next(),
|
||||||
|
elasticsearchConverter,
|
||||||
|
routingResolver)) //
|
||||||
.collect(Collectors.toList()); //
|
.collect(Collectors.toList()); //
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,47 +400,6 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
|
|||||||
|
|
||||||
return updateQueryBuilder.build();
|
return updateQueryBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <T> T updateIndexedObject(T entity, IndexedObjectInformation indexedObjectInformation) {
|
|
||||||
|
|
||||||
ElasticsearchPersistentEntity<?> persistentEntity = elasticsearchConverter.getMappingContext()
|
|
||||||
.getPersistentEntity(entity.getClass());
|
|
||||||
|
|
||||||
if (persistentEntity != null) {
|
|
||||||
PersistentPropertyAccessor<Object> propertyAccessor = persistentEntity.getPropertyAccessor(entity);
|
|
||||||
ElasticsearchPersistentProperty idProperty = persistentEntity.getIdProperty();
|
|
||||||
|
|
||||||
// Only deal with text because ES generated Ids are strings!
|
|
||||||
if (indexedObjectInformation.id() != null && idProperty != null && idProperty.isReadable()
|
|
||||||
&& idProperty.getType().isAssignableFrom(String.class)) {
|
|
||||||
propertyAccessor.setProperty(idProperty, indexedObjectInformation.id());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (indexedObjectInformation.seqNo() != null && indexedObjectInformation.primaryTerm() != null
|
|
||||||
&& persistentEntity.hasSeqNoPrimaryTermProperty()) {
|
|
||||||
ElasticsearchPersistentProperty seqNoPrimaryTermProperty = persistentEntity.getSeqNoPrimaryTermProperty();
|
|
||||||
// noinspection ConstantConditions
|
|
||||||
propertyAccessor.setProperty(seqNoPrimaryTermProperty,
|
|
||||||
new SeqNoPrimaryTerm(indexedObjectInformation.seqNo(), indexedObjectInformation.primaryTerm()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (indexedObjectInformation.version() != null && persistentEntity.hasVersionProperty()) {
|
|
||||||
ElasticsearchPersistentProperty versionProperty = persistentEntity.getVersionProperty();
|
|
||||||
// noinspection ConstantConditions
|
|
||||||
propertyAccessor.setProperty(versionProperty, indexedObjectInformation.version());
|
|
||||||
}
|
|
||||||
|
|
||||||
var indexedIndexNameProperty = persistentEntity.getIndexedIndexNameProperty();
|
|
||||||
if (indexedIndexNameProperty != null) {
|
|
||||||
propertyAccessor.setProperty(indexedIndexNameProperty, indexedObjectInformation.index());
|
|
||||||
}
|
|
||||||
|
|
||||||
// noinspection unchecked
|
|
||||||
return (T) propertyAccessor.getBean();
|
|
||||||
}
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region SearchOperations
|
// region SearchOperations
|
||||||
@ -736,7 +698,11 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
|
|||||||
Object queryObject = indexQuery.getObject();
|
Object queryObject = indexQuery.getObject();
|
||||||
|
|
||||||
if (queryObject != null) {
|
if (queryObject != null) {
|
||||||
indexQuery.setObject(updateIndexedObject(queryObject, indexedObjectInformationList.get(i)));
|
indexQuery.setObject(entityOperations.updateIndexedObject(
|
||||||
|
queryObject,
|
||||||
|
indexedObjectInformationList.get(i),
|
||||||
|
elasticsearchConverter,
|
||||||
|
routingResolver));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -802,7 +768,11 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
|
|||||||
documentAfterLoad.hasSeqNo() ? documentAfterLoad.getSeqNo() : null, //
|
documentAfterLoad.hasSeqNo() ? documentAfterLoad.getSeqNo() : null, //
|
||||||
documentAfterLoad.hasPrimaryTerm() ? documentAfterLoad.getPrimaryTerm() : null, //
|
documentAfterLoad.hasPrimaryTerm() ? documentAfterLoad.getPrimaryTerm() : null, //
|
||||||
documentAfterLoad.hasVersion() ? documentAfterLoad.getVersion() : null); //
|
documentAfterLoad.hasVersion() ? documentAfterLoad.getVersion() : null); //
|
||||||
entity = updateIndexedObject(entity, indexedObjectInformation);
|
entity = entityOperations.updateIndexedObject(
|
||||||
|
entity,
|
||||||
|
indexedObjectInformation,
|
||||||
|
elasticsearchConverter,
|
||||||
|
routingResolver);
|
||||||
|
|
||||||
return maybeCallbackAfterConvert(entity, documentAfterLoad, index);
|
return maybeCallbackAfterConvert(entity, documentAfterLoad, index);
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,6 @@ import org.springframework.data.elasticsearch.core.event.ReactiveAfterLoadCallba
|
|||||||
import org.springframework.data.elasticsearch.core.event.ReactiveAfterSaveCallback;
|
import org.springframework.data.elasticsearch.core.event.ReactiveAfterSaveCallback;
|
||||||
import org.springframework.data.elasticsearch.core.event.ReactiveBeforeConvertCallback;
|
import org.springframework.data.elasticsearch.core.event.ReactiveBeforeConvertCallback;
|
||||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
|
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
|
||||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
|
|
||||||
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
|
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
|
||||||
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
||||||
import org.springframework.data.elasticsearch.core.query.ByQueryResponse;
|
import org.springframework.data.elasticsearch.core.query.ByQueryResponse;
|
||||||
@ -55,7 +54,6 @@ import org.springframework.data.elasticsearch.core.routing.RoutingResolver;
|
|||||||
import org.springframework.data.elasticsearch.core.script.Script;
|
import org.springframework.data.elasticsearch.core.script.Script;
|
||||||
import org.springframework.data.elasticsearch.core.suggest.response.Suggest;
|
import org.springframework.data.elasticsearch.core.suggest.response.Suggest;
|
||||||
import org.springframework.data.elasticsearch.support.VersionInfo;
|
import org.springframework.data.elasticsearch.support.VersionInfo;
|
||||||
import org.springframework.data.mapping.PersistentPropertyAccessor;
|
|
||||||
import org.springframework.data.mapping.callback.ReactiveEntityCallbacks;
|
import org.springframework.data.mapping.callback.ReactiveEntityCallbacks;
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
@ -320,51 +318,6 @@ abstract public class AbstractReactiveElasticsearchTemplate
|
|||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <T> T updateIndexedObject(T entity, IndexedObjectInformation indexedObjectInformation) {
|
|
||||||
|
|
||||||
ElasticsearchPersistentEntity<?> persistentEntity = converter.getMappingContext()
|
|
||||||
.getPersistentEntity(entity.getClass());
|
|
||||||
|
|
||||||
if (persistentEntity != null) {
|
|
||||||
// noinspection DuplicatedCode
|
|
||||||
PersistentPropertyAccessor<Object> propertyAccessor = persistentEntity.getPropertyAccessor(entity);
|
|
||||||
ElasticsearchPersistentProperty idProperty = persistentEntity.getIdProperty();
|
|
||||||
|
|
||||||
// Only deal with text because ES generated Ids are strings!
|
|
||||||
if (indexedObjectInformation.id() != null && idProperty != null && idProperty.isReadable()
|
|
||||||
&& idProperty.getType().isAssignableFrom(String.class)) {
|
|
||||||
propertyAccessor.setProperty(idProperty, indexedObjectInformation.id());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (indexedObjectInformation.seqNo() != null && indexedObjectInformation.primaryTerm() != null
|
|
||||||
&& persistentEntity.hasSeqNoPrimaryTermProperty()) {
|
|
||||||
ElasticsearchPersistentProperty seqNoPrimaryTermProperty = persistentEntity.getSeqNoPrimaryTermProperty();
|
|
||||||
// noinspection ConstantConditions
|
|
||||||
propertyAccessor.setProperty(seqNoPrimaryTermProperty,
|
|
||||||
new SeqNoPrimaryTerm(indexedObjectInformation.seqNo(), indexedObjectInformation.primaryTerm()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (indexedObjectInformation.version() != null && persistentEntity.hasVersionProperty()) {
|
|
||||||
ElasticsearchPersistentProperty versionProperty = persistentEntity.getVersionProperty();
|
|
||||||
// noinspection ConstantConditions
|
|
||||||
propertyAccessor.setProperty(versionProperty, indexedObjectInformation.version());
|
|
||||||
}
|
|
||||||
|
|
||||||
var indexedIndexNameProperty = persistentEntity.getIndexedIndexNameProperty();
|
|
||||||
if (indexedIndexNameProperty != null) {
|
|
||||||
propertyAccessor.setProperty(indexedIndexNameProperty, indexedObjectInformation.index());
|
|
||||||
}
|
|
||||||
|
|
||||||
// noinspection unchecked
|
|
||||||
return (T) propertyAccessor.getBean();
|
|
||||||
} else {
|
|
||||||
EntityOperations.AdaptableEntity<T> adaptableEntity = entityOperations.forEntity(entity,
|
|
||||||
converter.getConversionService(), routingResolver);
|
|
||||||
adaptableEntity.populateIdIfNecessary(indexedObjectInformation.id());
|
|
||||||
}
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> Flux<MultiGetItem<T>> multiGet(Query query, Class<T> clazz) {
|
public <T> Flux<MultiGetItem<T>> multiGet(Query query, Class<T> clazz) {
|
||||||
return multiGet(query, clazz, getIndexCoordinatesFor(clazz));
|
return multiGet(query, clazz, getIndexCoordinatesFor(clazz));
|
||||||
@ -391,12 +344,16 @@ abstract public class AbstractReactiveElasticsearchTemplate
|
|||||||
.map(it -> {
|
.map(it -> {
|
||||||
T savedEntity = it.getT1();
|
T savedEntity = it.getT1();
|
||||||
IndexResponseMetaData indexResponseMetaData = it.getT2();
|
IndexResponseMetaData indexResponseMetaData = it.getT2();
|
||||||
return updateIndexedObject(savedEntity, new IndexedObjectInformation(
|
return entityOperations.updateIndexedObject(
|
||||||
|
savedEntity,
|
||||||
|
new IndexedObjectInformation(
|
||||||
indexResponseMetaData.id(),
|
indexResponseMetaData.id(),
|
||||||
indexResponseMetaData.index(),
|
indexResponseMetaData.index(),
|
||||||
indexResponseMetaData.seqNo(),
|
indexResponseMetaData.seqNo(),
|
||||||
indexResponseMetaData.primaryTerm(),
|
indexResponseMetaData.primaryTerm(),
|
||||||
indexResponseMetaData.version()));
|
indexResponseMetaData.version()),
|
||||||
|
converter,
|
||||||
|
routingResolver);
|
||||||
}).flatMap(saved -> maybeCallbackAfterSave(saved, index));
|
}).flatMap(saved -> maybeCallbackAfterSave(saved, index));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -652,7 +609,11 @@ abstract public class AbstractReactiveElasticsearchTemplate
|
|||||||
documentAfterLoad.hasSeqNo() ? documentAfterLoad.getSeqNo() : null,
|
documentAfterLoad.hasSeqNo() ? documentAfterLoad.getSeqNo() : null,
|
||||||
documentAfterLoad.hasPrimaryTerm() ? documentAfterLoad.getPrimaryTerm() : null,
|
documentAfterLoad.hasPrimaryTerm() ? documentAfterLoad.getPrimaryTerm() : null,
|
||||||
documentAfterLoad.hasVersion() ? documentAfterLoad.getVersion() : null);
|
documentAfterLoad.hasVersion() ? documentAfterLoad.getVersion() : null);
|
||||||
entity = updateIndexedObject(entity, indexedObjectInformation);
|
entity = entityOperations.updateIndexedObject(
|
||||||
|
entity,
|
||||||
|
indexedObjectInformation,
|
||||||
|
converter,
|
||||||
|
routingResolver);
|
||||||
|
|
||||||
return maybeCallbackAfterConvert(entity, documentAfterLoad, index);
|
return maybeCallbackAfterConvert(entity, documentAfterLoad, index);
|
||||||
});
|
});
|
||||||
|
@ -18,6 +18,7 @@ package org.springframework.data.elasticsearch.core;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.springframework.core.convert.ConversionService;
|
import org.springframework.core.convert.ConversionService;
|
||||||
|
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
||||||
import org.springframework.data.elasticsearch.core.join.JoinField;
|
import org.springframework.data.elasticsearch.core.join.JoinField;
|
||||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
|
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
|
||||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
|
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
|
||||||
@ -94,6 +95,69 @@ public class EntityOperations {
|
|||||||
return AdaptableMappedEntity.of(entity, context, conversionService, routingResolver);
|
return AdaptableMappedEntity.of(entity, context, conversionService, routingResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an entity after it is stored in Elasticsearch with additional data like id, version, seqno...
|
||||||
|
*
|
||||||
|
* @param <T> the entity class
|
||||||
|
* @param entity the entity to update
|
||||||
|
* @param indexedObjectInformation the update information
|
||||||
|
* @param elasticsearchConverter the converter providing necessary mapping information
|
||||||
|
* @param routingResolver routing resolver to use
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public <T> T updateIndexedObject(T entity,
|
||||||
|
IndexedObjectInformation indexedObjectInformation,
|
||||||
|
ElasticsearchConverter elasticsearchConverter,
|
||||||
|
RoutingResolver routingResolver) {
|
||||||
|
|
||||||
|
Assert.notNull(entity, "entity must not be null");
|
||||||
|
Assert.notNull(indexedObjectInformation, "indexedObjectInformation must not be null");
|
||||||
|
Assert.notNull(elasticsearchConverter, "elasticsearchConverter must not be null");
|
||||||
|
|
||||||
|
ElasticsearchPersistentEntity<?> persistentEntity = elasticsearchConverter.getMappingContext()
|
||||||
|
.getPersistentEntity(entity.getClass());
|
||||||
|
|
||||||
|
if (persistentEntity != null) {
|
||||||
|
PersistentPropertyAccessor<Object> propertyAccessor = persistentEntity.getPropertyAccessor(entity);
|
||||||
|
ElasticsearchPersistentProperty idProperty = persistentEntity.getIdProperty();
|
||||||
|
|
||||||
|
// Only deal with text because ES generated Ids are strings!
|
||||||
|
if (indexedObjectInformation.id() != null && idProperty != null
|
||||||
|
// isReadable from the base class is false in case of records
|
||||||
|
&& (idProperty.isReadable() || idProperty.getOwner().getType().isRecord())
|
||||||
|
&& idProperty.getType().isAssignableFrom(String.class)) {
|
||||||
|
propertyAccessor.setProperty(idProperty, indexedObjectInformation.id());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indexedObjectInformation.seqNo() != null && indexedObjectInformation.primaryTerm() != null
|
||||||
|
&& persistentEntity.hasSeqNoPrimaryTermProperty()) {
|
||||||
|
ElasticsearchPersistentProperty seqNoPrimaryTermProperty = persistentEntity.getSeqNoPrimaryTermProperty();
|
||||||
|
// noinspection ConstantConditions
|
||||||
|
propertyAccessor.setProperty(seqNoPrimaryTermProperty,
|
||||||
|
new SeqNoPrimaryTerm(indexedObjectInformation.seqNo(), indexedObjectInformation.primaryTerm()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indexedObjectInformation.version() != null && persistentEntity.hasVersionProperty()) {
|
||||||
|
ElasticsearchPersistentProperty versionProperty = persistentEntity.getVersionProperty();
|
||||||
|
// noinspection ConstantConditions
|
||||||
|
propertyAccessor.setProperty(versionProperty, indexedObjectInformation.version());
|
||||||
|
}
|
||||||
|
|
||||||
|
var indexedIndexNameProperty = persistentEntity.getIndexedIndexNameProperty();
|
||||||
|
if (indexedIndexNameProperty != null) {
|
||||||
|
propertyAccessor.setProperty(indexedIndexNameProperty, indexedObjectInformation.index());
|
||||||
|
}
|
||||||
|
|
||||||
|
// noinspection unchecked
|
||||||
|
return (T) propertyAccessor.getBean();
|
||||||
|
} else {
|
||||||
|
EntityOperations.AdaptableEntity<T> adaptableEntity = forEntity(entity,
|
||||||
|
elasticsearchConverter.getConversionService(), routingResolver);
|
||||||
|
adaptableEntity.populateIdIfNecessary(indexedObjectInformation.id());
|
||||||
|
}
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine index name and type name from {@link Entity} with {@code index} and {@code type} overrides. Allows using
|
* Determine index name and type name from {@link Entity} with {@code index} and {@code type} overrides. Allows using
|
||||||
* preferred values for index and type if provided, otherwise fall back to index and type defined on entity level.
|
* preferred values for index and type if provided, otherwise fall back to index and type defined on entity level.
|
||||||
|
@ -20,17 +20,24 @@ import static org.assertj.core.api.Assertions.*;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import org.assertj.core.api.SoftAssertions;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.core.convert.ConversionService;
|
import org.springframework.core.convert.ConversionService;
|
||||||
import org.springframework.core.convert.support.GenericConversionService;
|
import org.springframework.core.convert.support.GenericConversionService;
|
||||||
import org.springframework.data.annotation.Id;
|
import org.springframework.data.annotation.Id;
|
||||||
|
import org.springframework.data.annotation.Version;
|
||||||
import org.springframework.data.elasticsearch.annotations.Document;
|
import org.springframework.data.elasticsearch.annotations.Document;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.Field;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.IndexedIndexName;
|
||||||
import org.springframework.data.elasticsearch.annotations.Routing;
|
import org.springframework.data.elasticsearch.annotations.Routing;
|
||||||
|
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
||||||
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
|
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
|
||||||
import org.springframework.data.elasticsearch.core.join.JoinField;
|
import org.springframework.data.elasticsearch.core.join.JoinField;
|
||||||
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
||||||
|
import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm;
|
||||||
import org.springframework.data.elasticsearch.core.routing.DefaultRoutingResolver;
|
import org.springframework.data.elasticsearch.core.routing.DefaultRoutingResolver;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
@ -39,22 +46,24 @@ import org.springframework.lang.Nullable;
|
|||||||
*/
|
*/
|
||||||
class EntityOperationsUnitTests {
|
class EntityOperationsUnitTests {
|
||||||
|
|
||||||
@Nullable private static ConversionService conversionService;
|
|
||||||
@Nullable private static EntityOperations entityOperations;
|
|
||||||
@Nullable private static SimpleElasticsearchMappingContext mappingContext;
|
@Nullable private static SimpleElasticsearchMappingContext mappingContext;
|
||||||
|
@Nullable private static EntityOperations entityOperations;
|
||||||
|
@Nullable private static ElasticsearchConverter elasticsearchConverter;
|
||||||
|
@Nullable private static ConversionService conversionService;
|
||||||
|
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
static void setUpAll() {
|
static void setUpAll() {
|
||||||
mappingContext = new SimpleElasticsearchMappingContext();
|
mappingContext = new SimpleElasticsearchMappingContext();
|
||||||
mappingContext.setInitialEntitySet(new HashSet<>(Arrays.asList(EntityWithRouting.class)));
|
mappingContext.setInitialEntitySet(new HashSet<>(Arrays.asList(EntityWithRouting.class)));
|
||||||
mappingContext.afterPropertiesSet();
|
mappingContext.afterPropertiesSet();
|
||||||
|
|
||||||
entityOperations = new EntityOperations(mappingContext);
|
entityOperations = new EntityOperations(mappingContext);
|
||||||
|
|
||||||
MappingElasticsearchConverter converter = new MappingElasticsearchConverter(mappingContext,
|
elasticsearchConverter = new MappingElasticsearchConverter(mappingContext,
|
||||||
new GenericConversionService());
|
new GenericConversionService());
|
||||||
converter.afterPropertiesSet();
|
((MappingElasticsearchConverter) elasticsearchConverter).afterPropertiesSet();
|
||||||
|
|
||||||
conversionService = converter.getConversionService();
|
conversionService = elasticsearchConverter.getConversionService();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // #1218
|
@Test // #1218
|
||||||
@ -104,6 +113,64 @@ class EntityOperationsUnitTests {
|
|||||||
assertThat(routing).isEqualTo("theRoute");
|
assertThat(routing).isEqualTo("theRoute");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // #2756
|
||||||
|
@DisplayName("should update indexed information of class entity")
|
||||||
|
void shouldUpdateIndexedInformationOfClassEntity() {
|
||||||
|
|
||||||
|
var entity = new EntityFromClass();
|
||||||
|
entity.setId(null);
|
||||||
|
entity.setText("some text");
|
||||||
|
var indexedObjectInformation = new IndexedObjectInformation(
|
||||||
|
"id-42",
|
||||||
|
"index-42",
|
||||||
|
1L,
|
||||||
|
2L,
|
||||||
|
3L);
|
||||||
|
entity = entityOperations.updateIndexedObject(entity,
|
||||||
|
indexedObjectInformation,
|
||||||
|
elasticsearchConverter,
|
||||||
|
new DefaultRoutingResolver(mappingContext));
|
||||||
|
|
||||||
|
SoftAssertions softly = new SoftAssertions();
|
||||||
|
softly.assertThat(entity.getId()).isEqualTo(indexedObjectInformation.id());
|
||||||
|
softly.assertThat(entity.getSeqNoPrimaryTerm().sequenceNumber()).isEqualTo(indexedObjectInformation.seqNo());
|
||||||
|
softly.assertThat(entity.getSeqNoPrimaryTerm().primaryTerm()).isEqualTo(indexedObjectInformation.primaryTerm());
|
||||||
|
softly.assertThat(entity.getVersion()).isEqualTo(indexedObjectInformation.version());
|
||||||
|
softly.assertThat(entity.getIndexName()).isEqualTo(indexedObjectInformation.index());
|
||||||
|
softly.assertAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // #2756
|
||||||
|
@DisplayName("should update indexed information of record entity")
|
||||||
|
void shouldUpdateIndexedInformationOfRecordEntity() {
|
||||||
|
|
||||||
|
var entity = new EntityFromRecord(
|
||||||
|
null,
|
||||||
|
"someText",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null);
|
||||||
|
|
||||||
|
var indexedObjectInformation = new IndexedObjectInformation(
|
||||||
|
"id-42",
|
||||||
|
"index-42",
|
||||||
|
1L,
|
||||||
|
2L,
|
||||||
|
3L);
|
||||||
|
entity = entityOperations.updateIndexedObject(entity,
|
||||||
|
indexedObjectInformation,
|
||||||
|
elasticsearchConverter,
|
||||||
|
new DefaultRoutingResolver(mappingContext));
|
||||||
|
|
||||||
|
SoftAssertions softly = new SoftAssertions();
|
||||||
|
softly.assertThat(entity.id()).isEqualTo(indexedObjectInformation.id());
|
||||||
|
softly.assertThat(entity.seqNoPrimaryTerm().sequenceNumber()).isEqualTo(indexedObjectInformation.seqNo());
|
||||||
|
softly.assertThat(entity.seqNoPrimaryTerm().primaryTerm()).isEqualTo(indexedObjectInformation.primaryTerm());
|
||||||
|
softly.assertThat(entity.version()).isEqualTo(indexedObjectInformation.version());
|
||||||
|
softly.assertThat(entity.indexName()).isEqualTo(indexedObjectInformation.index());
|
||||||
|
softly.assertAll();
|
||||||
|
}
|
||||||
|
|
||||||
@Document(indexName = "entity-operations-test")
|
@Document(indexName = "entity-operations-test")
|
||||||
@Routing("routing")
|
@Routing("routing")
|
||||||
static class EntityWithRouting {
|
static class EntityWithRouting {
|
||||||
@ -165,4 +232,70 @@ class EntityOperationsUnitTests {
|
|||||||
this.joinField = joinField;
|
this.joinField = joinField;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Document(indexName = "entity-operations-test")
|
||||||
|
static class EntityFromClass {
|
||||||
|
@Id
|
||||||
|
@Nullable private String id;
|
||||||
|
@Field(type = FieldType.Text)
|
||||||
|
@Nullable private String text;
|
||||||
|
@Version
|
||||||
|
@Nullable private Long version;
|
||||||
|
@Nullable private SeqNoPrimaryTerm seqNoPrimaryTerm;
|
||||||
|
@IndexedIndexName
|
||||||
|
@Nullable private String indexName;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(@Nullable String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Long getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(@Nullable Long version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public SeqNoPrimaryTerm getSeqNoPrimaryTerm() {
|
||||||
|
return seqNoPrimaryTerm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSeqNoPrimaryTerm(@Nullable SeqNoPrimaryTerm seqNoPrimaryTerm) {
|
||||||
|
this.seqNoPrimaryTerm = seqNoPrimaryTerm;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getIndexName() {
|
||||||
|
return indexName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIndexName(@Nullable String indexName) {
|
||||||
|
this.indexName = indexName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Document(indexName = "entity-operations-test")
|
||||||
|
static record EntityFromRecord(
|
||||||
|
@Id @Nullable String id,
|
||||||
|
@Field(type = FieldType.Text) @Nullable String text,
|
||||||
|
@Version @Nullable Long version,
|
||||||
|
@Nullable SeqNoPrimaryTerm seqNoPrimaryTerm,
|
||||||
|
@IndexedIndexName @Nullable String indexName) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user