mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-06-30 15:52:12 +00:00
Introduce MappingConversionException.
Original Pull Request #2882 Closes #2879
This commit is contained in:
parent
0a51dbab01
commit
6d51e67948
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2024 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.core.convert;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* @since 5.3
|
||||
* @author Peter-Josef Meisch
|
||||
*/
|
||||
public class MappingConversionException extends RuntimeException {
|
||||
private final String documentId;
|
||||
|
||||
public MappingConversionException(@Nullable String documentId, Throwable cause) {
|
||||
super(cause);
|
||||
this.documentId = documentId != null ? documentId : "\"null\"";
|
||||
}
|
||||
|
||||
public String getDocumentId() {
|
||||
return documentId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "Conversion exception when converting document id " + documentId;
|
||||
}
|
||||
}
|
@ -65,6 +65,8 @@ import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import javax.print.Doc;
|
||||
|
||||
/**
|
||||
* Elasticsearch specific {@link org.springframework.data.convert.EntityConverter} implementation based on domain type
|
||||
* {@link ElasticsearchPersistentEntity metadata}.
|
||||
@ -333,46 +335,52 @@ public class MappingElasticsearchConverter
|
||||
return instance;
|
||||
}
|
||||
|
||||
Document document = (source instanceof Document) ? (Document) source : null;
|
||||
|
||||
ElasticsearchPropertyValueProvider valueProvider = new ElasticsearchPropertyValueProvider(accessor, evaluator);
|
||||
R result = readProperties(targetEntity, instance, valueProvider);
|
||||
try {
|
||||
R result = readProperties(targetEntity, instance, valueProvider);
|
||||
|
||||
if (source instanceof Document document) {
|
||||
if (document.hasId()) {
|
||||
ElasticsearchPersistentProperty idProperty = targetEntity.getIdProperty();
|
||||
PersistentPropertyAccessor<R> propertyAccessor = new ConvertingPropertyAccessor<>(
|
||||
targetEntity.getPropertyAccessor(result), conversionService);
|
||||
// Only deal with String because ES generated Ids are strings !
|
||||
if (idProperty != null && idProperty.isReadable() && idProperty.getType().isAssignableFrom(String.class)) {
|
||||
propertyAccessor.setProperty(idProperty, document.getId());
|
||||
if (document != null) {
|
||||
if (document.hasId()) {
|
||||
ElasticsearchPersistentProperty idProperty = targetEntity.getIdProperty();
|
||||
PersistentPropertyAccessor<R> propertyAccessor = new ConvertingPropertyAccessor<>(
|
||||
targetEntity.getPropertyAccessor(result), conversionService);
|
||||
// Only deal with String because ES generated Ids are strings !
|
||||
if (idProperty != null && idProperty.isReadable() && idProperty.getType().isAssignableFrom(String.class)) {
|
||||
propertyAccessor.setProperty(idProperty, document.getId());
|
||||
}
|
||||
}
|
||||
|
||||
if (document.hasVersion()) {
|
||||
long version = document.getVersion();
|
||||
ElasticsearchPersistentProperty versionProperty = targetEntity.getVersionProperty();
|
||||
// Only deal with Long because ES versions are longs !
|
||||
if (versionProperty != null && versionProperty.getType().isAssignableFrom(Long.class)) {
|
||||
// check that a version was actually returned in the response, -1 would indicate that
|
||||
// a search didn't request the version ids in the response, which would be an issue
|
||||
Assert.isTrue(version != -1, "Version in response is -1");
|
||||
targetEntity.getPropertyAccessor(result).setProperty(versionProperty, version);
|
||||
}
|
||||
}
|
||||
|
||||
if (targetEntity.hasSeqNoPrimaryTermProperty() && document.hasSeqNo() && document.hasPrimaryTerm()) {
|
||||
if (isAssignedSeqNo(document.getSeqNo()) && isAssignedPrimaryTerm(document.getPrimaryTerm())) {
|
||||
SeqNoPrimaryTerm seqNoPrimaryTerm = new SeqNoPrimaryTerm(document.getSeqNo(), document.getPrimaryTerm());
|
||||
ElasticsearchPersistentProperty property = targetEntity.getRequiredSeqNoPrimaryTermProperty();
|
||||
targetEntity.getPropertyAccessor(result).setProperty(property, seqNoPrimaryTerm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (document.hasVersion()) {
|
||||
long version = document.getVersion();
|
||||
ElasticsearchPersistentProperty versionProperty = targetEntity.getVersionProperty();
|
||||
// Only deal with Long because ES versions are longs !
|
||||
if (versionProperty != null && versionProperty.getType().isAssignableFrom(Long.class)) {
|
||||
// check that a version was actually returned in the response, -1 would indicate that
|
||||
// a search didn't request the version ids in the response, which would be an issue
|
||||
Assert.isTrue(version != -1, "Version in response is -1");
|
||||
targetEntity.getPropertyAccessor(result).setProperty(versionProperty, version);
|
||||
}
|
||||
}
|
||||
|
||||
if (targetEntity.hasSeqNoPrimaryTermProperty() && document.hasSeqNo() && document.hasPrimaryTerm()) {
|
||||
if (isAssignedSeqNo(document.getSeqNo()) && isAssignedPrimaryTerm(document.getPrimaryTerm())) {
|
||||
SeqNoPrimaryTerm seqNoPrimaryTerm = new SeqNoPrimaryTerm(document.getSeqNo(), document.getPrimaryTerm());
|
||||
ElasticsearchPersistentProperty property = targetEntity.getRequiredSeqNoPrimaryTermProperty();
|
||||
targetEntity.getPropertyAccessor(result).setProperty(property, seqNoPrimaryTerm);
|
||||
}
|
||||
if (source instanceof SearchDocument searchDocument) {
|
||||
populateScriptFields(targetEntity, result, searchDocument);
|
||||
}
|
||||
return result;
|
||||
} catch (ConversionException e) {
|
||||
String documentId = (document != null && document.hasId()) ? document.getId() : null;
|
||||
throw new MappingConversionException(documentId, e);
|
||||
}
|
||||
|
||||
if (source instanceof SearchDocument searchDocument) {
|
||||
populateScriptFields(targetEntity, result, searchDocument);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private ParameterValueProvider<ElasticsearchPersistentProperty> getParameterProvider(
|
||||
@ -510,11 +518,9 @@ public class MappingElasticsearchConverter
|
||||
}
|
||||
|
||||
if (source instanceof List<?> list) {
|
||||
source = list.stream().map(it -> convertOnRead(propertyValueConverter, it))
|
||||
.collect(Collectors.toList());
|
||||
source = list.stream().map(it -> convertOnRead(propertyValueConverter, it)).collect(Collectors.toList());
|
||||
} else if (source instanceof Set<?> set) {
|
||||
source = set.stream().map(it -> convertOnRead(propertyValueConverter, it))
|
||||
.collect(Collectors.toSet());
|
||||
source = set.stream().map(it -> convertOnRead(propertyValueConverter, it)).collect(Collectors.toSet());
|
||||
} else {
|
||||
source = convertOnRead(propertyValueConverter, source);
|
||||
}
|
||||
|
@ -228,6 +228,13 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
"org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverterUnitTests$Notification");
|
||||
}
|
||||
|
||||
private Map<String, Object> writeToMap(Object source) {
|
||||
|
||||
Document sink = Document.create();
|
||||
mappingElasticsearchConverter.write(source, sink);
|
||||
return sink;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFailToInitializeGivenMappingContextIsNull() {
|
||||
|
||||
@ -993,7 +1000,7 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
"nullRange": null,
|
||||
"integerRangeList": [
|
||||
{
|
||||
"gte": "2",
|
||||
"gte": "2",
|
||||
"lte": "5"
|
||||
}
|
||||
]
|
||||
@ -1178,11 +1185,13 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
public void setIntegerRangeList(List<Range<Integer>> integerRangeList) {
|
||||
this.integerRangeList = integerRangeList;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class GeoJsonUnitTests {
|
||||
|
||||
private GeoJsonEntity entity;
|
||||
|
||||
@BeforeEach
|
||||
@ -1476,6 +1485,7 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
|
||||
assertThat(entity).isEqualTo(mapped);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test // #1454
|
||||
@ -1942,13 +1952,6 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
assertThat(names).containsExactlyInAnyOrder("child1", "child2");
|
||||
}
|
||||
|
||||
private Map<String, Object> writeToMap(Object source) {
|
||||
|
||||
Document sink = Document.create();
|
||||
mappingElasticsearchConverter.write(source, sink);
|
||||
return sink;
|
||||
}
|
||||
|
||||
@Test // #2364
|
||||
@DisplayName("should not write id property to document source if configured so")
|
||||
void shouldNotWriteIdPropertyToDocumentSourceIfConfiguredSo() throws JSONException {
|
||||
@ -2078,6 +2081,25 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
assertThat(mappedNames).isEqualTo("level-one.level-two.key-word");
|
||||
}
|
||||
|
||||
@Test // #2879
|
||||
@DisplayName("should throw MappingConversionException with document id on reading error")
|
||||
void shouldThrowMappingConversionExceptionWithDocumentIdOnReadingError() {
|
||||
|
||||
@Language("JSON")
|
||||
String json = """
|
||||
{
|
||||
"birth-date": "this-is-not-a-local-date"
|
||||
}""";
|
||||
|
||||
Document document = Document.parse(json);
|
||||
document.setId("42");
|
||||
|
||||
assertThatThrownBy(() -> {
|
||||
mappingElasticsearchConverter.read(Person.class, document);
|
||||
}).isInstanceOf(MappingConversionException.class).hasFieldOrPropertyWithValue("documentId", "42")
|
||||
.hasCauseInstanceOf(ConversionException.class);
|
||||
}
|
||||
|
||||
// region entities
|
||||
public static class Sample {
|
||||
@Nullable public @ReadOnlyProperty String readOnly;
|
||||
|
Loading…
x
Reference in New Issue
Block a user