mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-06-08 21:22:12 +00:00
Add custom property converters.
Original Pull Request #1953 Closes #1945
This commit is contained in:
parent
464fc31d87
commit
7ae55b9e75
@ -71,3 +71,8 @@ Spring Data Elasticsearch now uses `org.springframework.data.elasticsearch.core.
|
||||
=== Completion classes
|
||||
|
||||
The classes from the package `org.springframework.data.elasticsearch.core.completion` have been moved to `org.springframework.data.elasticsearch.core.suggest`.
|
||||
|
||||
=== Other renamings
|
||||
|
||||
The `org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentPropertyConverter` interface has been renamed to `org.springframework.data.elasticsearch.core.mapping.PropertyValueConverter`.
|
||||
Likewise the implementations classes named _XXPersistentPropertyConverter_ have been renamed to _XXPropertyValueConverter_.
|
||||
|
@ -56,6 +56,8 @@ This means, that no mapping entry is written for the property and that Elasticse
|
||||
** `analyzer`, `searchAnalyzer`, `normalizer` for specifying custom analyzers and normalizer.
|
||||
* `@GeoPoint`: Marks a field as _geo_point_ datatype.
|
||||
Can be omitted if the field is an instance of the `GeoPoint` class.
|
||||
* `@ValueConverter` defines a class to be used to convert the given property.
|
||||
In difference to a registered Spring `Converter` this only converts the annotated property and not every property of the given type.
|
||||
|
||||
The mapping metadata infrastructure is defined in a separate spring-data-commons project that is technology agnostic.
|
||||
|
||||
@ -184,6 +186,7 @@ public class Person { <1>
|
||||
"lastname" : "Connor"
|
||||
}
|
||||
----
|
||||
|
||||
<1> By default the domain types class name is used for the type hint.
|
||||
====
|
||||
|
||||
@ -211,6 +214,7 @@ public class Person {
|
||||
"id" : ...
|
||||
}
|
||||
----
|
||||
|
||||
<1> The configured alias is used when writing the entity.
|
||||
====
|
||||
|
||||
@ -421,6 +425,7 @@ public class Config extends AbstractElasticsearchConfiguration {
|
||||
"localidad" : { "lat" : 34.118347, "lon" : -118.3026284 }
|
||||
}
|
||||
----
|
||||
|
||||
<1> Add `Converter` implementations.
|
||||
<2> Set up the `Converter` used for writing `DomainType` to Elasticsearch.
|
||||
<3> Set up the `Converter` used for reading `DomainType` from search result.
|
||||
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2021 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.annotations;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.data.elasticsearch.core.mapping.PropertyValueConverter;
|
||||
|
||||
/**
|
||||
* Annotation to put on a property of an entity to define a value converter which can convert the property to a type
|
||||
* that Elasticsearch understands and back.
|
||||
*
|
||||
* @author Peter-Josef Meisch
|
||||
* @since 4.3
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.FIELD, ElementType.ANNOTATION_TYPE })
|
||||
@Documented
|
||||
@Inherited
|
||||
public @interface ValueConverter {
|
||||
|
||||
/**
|
||||
* Defines the class implementing the {@link PropertyValueConverter} interface. If this is a normal class, it must
|
||||
* provide a default constructor with no arguments. If this is an enum and thus implementing a singleton by enum it
|
||||
* must only have one enum value.
|
||||
*
|
||||
* @return the class to use for conversion
|
||||
*/
|
||||
Class<? extends PropertyValueConverter> value();
|
||||
}
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.core.convert;
|
||||
|
||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentPropertyConverter;
|
||||
import org.springframework.data.elasticsearch.core.mapping.PropertyValueConverter;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@ -23,11 +23,11 @@ import org.springframework.util.Assert;
|
||||
* @author Sascha Woo
|
||||
* @since 4.3
|
||||
*/
|
||||
public abstract class AbstractPersistentPropertyConverter implements ElasticsearchPersistentPropertyConverter {
|
||||
public abstract class AbstractPropertyValueConverter implements PropertyValueConverter {
|
||||
|
||||
private final PersistentProperty<?> property;
|
||||
|
||||
public AbstractPersistentPropertyConverter(PersistentProperty<?> property) {
|
||||
public AbstractPropertyValueConverter(PersistentProperty<?> property) {
|
||||
|
||||
Assert.notNull(property, "property must not be null.");
|
||||
this.property = property;
|
@ -26,14 +26,14 @@ import org.springframework.util.Assert;
|
||||
* @author Sascha Woo
|
||||
* @since 4.3
|
||||
*/
|
||||
public abstract class AbstractRangePersistentPropertyConverter<T> extends AbstractPersistentPropertyConverter {
|
||||
public abstract class AbstractRangePropertyValueConverter<T> extends AbstractPropertyValueConverter {
|
||||
|
||||
protected static final String LT_FIELD = "lt";
|
||||
protected static final String LTE_FIELD = "lte";
|
||||
protected static final String GT_FIELD = "gt";
|
||||
protected static final String GTE_FIELD = "gte";
|
||||
|
||||
public AbstractRangePersistentPropertyConverter(PersistentProperty<?> property) {
|
||||
public AbstractRangePropertyValueConverter(PersistentProperty<?> property) {
|
||||
super(property);
|
||||
}
|
||||
|
@ -26,14 +26,13 @@ import org.springframework.data.mapping.PersistentProperty;
|
||||
* @author Sascha Woo
|
||||
* @since 4.3
|
||||
*/
|
||||
public class DatePersistentPropertyConverter extends AbstractPersistentPropertyConverter {
|
||||
public class DatePropertyValueConverter extends AbstractPropertyValueConverter {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DatePersistentPropertyConverter.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DatePropertyValueConverter.class);
|
||||
|
||||
private final List<ElasticsearchDateConverter> dateConverters;
|
||||
|
||||
public DatePersistentPropertyConverter(PersistentProperty<?> property,
|
||||
List<ElasticsearchDateConverter> dateConverters) {
|
||||
public DatePropertyValueConverter(PersistentProperty<?> property, List<ElasticsearchDateConverter> dateConverters) {
|
||||
|
||||
super(property);
|
||||
this.dateConverters = dateConverters;
|
@ -26,13 +26,13 @@ import org.springframework.data.mapping.PersistentProperty;
|
||||
* @author Sascha Woo
|
||||
* @since 4.3
|
||||
*/
|
||||
public class DateRangePersistentPropertyConverter extends AbstractRangePersistentPropertyConverter<Date> {
|
||||
public class DateRangePropertyValueConverter extends AbstractRangePropertyValueConverter<Date> {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DateRangePersistentPropertyConverter.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DateRangePropertyValueConverter.class);
|
||||
|
||||
private final List<ElasticsearchDateConverter> dateConverters;
|
||||
|
||||
public DateRangePersistentPropertyConverter(PersistentProperty<?> property,
|
||||
public DateRangePropertyValueConverter(PersistentProperty<?> property,
|
||||
List<ElasticsearchDateConverter> dateConverters) {
|
||||
|
||||
super(property);
|
@ -19,6 +19,7 @@ import org.springframework.data.convert.EntityConverter;
|
||||
import org.springframework.data.elasticsearch.core.document.Document;
|
||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
|
||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
|
||||
import org.springframework.data.elasticsearch.core.mapping.PropertyValueConverter;
|
||||
import org.springframework.data.elasticsearch.core.query.Query;
|
||||
import org.springframework.data.projection.ProjectionFactory;
|
||||
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
|
||||
@ -93,8 +94,7 @@ public interface ElasticsearchConverter
|
||||
/**
|
||||
* Updates a {@link Query} by renaming the property names in the query to the correct mapped field names and the
|
||||
* values to the converted values if the {@link ElasticsearchPersistentProperty} for a property has a
|
||||
* {@link org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentPropertyConverter}. If
|
||||
* domainClass is null it's a noop.
|
||||
* {@link PropertyValueConverter}. If domainClass is null it's a noop.
|
||||
*
|
||||
* @param query the query that is internally updated, must not be {@literal null}
|
||||
* @param domainClass the class of the object that is searched with the query
|
||||
|
@ -39,7 +39,7 @@ import org.springframework.data.elasticsearch.core.document.Document;
|
||||
import org.springframework.data.elasticsearch.core.document.SearchDocument;
|
||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
|
||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
|
||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentPropertyConverter;
|
||||
import org.springframework.data.elasticsearch.core.mapping.PropertyValueConverter;
|
||||
import org.springframework.data.elasticsearch.core.query.Criteria;
|
||||
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
|
||||
import org.springframework.data.elasticsearch.core.query.FetchSourceFilter;
|
||||
@ -425,8 +425,9 @@ public class MappingElasticsearchConverter
|
||||
|
||||
Class<?> rawType = type.getType();
|
||||
|
||||
if (property.hasPropertyConverter()) {
|
||||
value = propertyConverterRead(property, value);
|
||||
if (property.hasPropertyValueConverter()) {
|
||||
// noinspection unchecked
|
||||
return (R) propertyConverterRead(property, value);
|
||||
} else if (TemporalAccessor.class.isAssignableFrom(property.getType())
|
||||
&& !conversions.hasCustomReadTarget(value.getClass(), rawType)) {
|
||||
|
||||
@ -466,8 +467,7 @@ public class MappingElasticsearchConverter
|
||||
}
|
||||
|
||||
private Object propertyConverterRead(ElasticsearchPersistentProperty property, Object source) {
|
||||
ElasticsearchPersistentPropertyConverter propertyConverter = Objects
|
||||
.requireNonNull(property.getPropertyConverter());
|
||||
PropertyValueConverter propertyValueConverter = Objects.requireNonNull(property.getPropertyValueConverter());
|
||||
|
||||
if (source instanceof String[]) {
|
||||
// convert to a List
|
||||
@ -475,18 +475,19 @@ public class MappingElasticsearchConverter
|
||||
}
|
||||
|
||||
if (source instanceof List) {
|
||||
source = ((List<?>) source).stream().map(it -> convertOnRead(propertyConverter, it))
|
||||
source = ((List<?>) source).stream().map(it -> convertOnRead(propertyValueConverter, it))
|
||||
.collect(Collectors.toList());
|
||||
} else if (source instanceof Set) {
|
||||
source = ((Set<?>) source).stream().map(it -> convertOnRead(propertyConverter, it)).collect(Collectors.toSet());
|
||||
source = ((Set<?>) source).stream().map(it -> convertOnRead(propertyValueConverter, it))
|
||||
.collect(Collectors.toSet());
|
||||
} else {
|
||||
source = convertOnRead(propertyConverter, source);
|
||||
source = convertOnRead(propertyValueConverter, source);
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
private Object convertOnRead(ElasticsearchPersistentPropertyConverter propertyConverter, Object source) {
|
||||
return propertyConverter.read(source);
|
||||
private Object convertOnRead(PropertyValueConverter propertyValueConverter, Object source) {
|
||||
return propertyValueConverter.read(source);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -897,7 +898,7 @@ public class MappingElasticsearchConverter
|
||||
continue;
|
||||
}
|
||||
|
||||
if (property.hasPropertyConverter()) {
|
||||
if (property.hasPropertyValueConverter()) {
|
||||
value = propertyConverterWrite(property, value);
|
||||
sink.set(property, value);
|
||||
} else if (TemporalAccessor.class.isAssignableFrom(property.getActualType())
|
||||
@ -1070,15 +1071,14 @@ public class MappingElasticsearchConverter
|
||||
}
|
||||
|
||||
private Object propertyConverterWrite(ElasticsearchPersistentProperty property, Object value) {
|
||||
ElasticsearchPersistentPropertyConverter propertyConverter = Objects
|
||||
.requireNonNull(property.getPropertyConverter());
|
||||
PropertyValueConverter propertyValueConverter = Objects.requireNonNull(property.getPropertyValueConverter());
|
||||
|
||||
if (value instanceof List) {
|
||||
value = ((List<?>) value).stream().map(propertyConverter::write).collect(Collectors.toList());
|
||||
value = ((List<?>) value).stream().map(propertyValueConverter::write).collect(Collectors.toList());
|
||||
} else if (value instanceof Set) {
|
||||
value = ((Set<?>) value).stream().map(propertyConverter::write).collect(Collectors.toSet());
|
||||
value = ((Set<?>) value).stream().map(propertyValueConverter::write).collect(Collectors.toSet());
|
||||
} else {
|
||||
value = propertyConverter.write(value);
|
||||
value = propertyValueConverter.write(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@ -1252,18 +1252,18 @@ public class MappingElasticsearchConverter
|
||||
|
||||
if (persistentProperty != null) {
|
||||
|
||||
if (persistentProperty.hasPropertyConverter()) {
|
||||
ElasticsearchPersistentPropertyConverter propertyConverter = Objects
|
||||
.requireNonNull(persistentProperty.getPropertyConverter());
|
||||
if (persistentProperty.hasPropertyValueConverter()) {
|
||||
PropertyValueConverter propertyValueConverter = Objects
|
||||
.requireNonNull(persistentProperty.getPropertyValueConverter());
|
||||
criteria.getQueryCriteriaEntries().forEach(criteriaEntry -> {
|
||||
Object value = criteriaEntry.getValue();
|
||||
if (value.getClass().isArray()) {
|
||||
Object[] objects = (Object[]) value;
|
||||
for (int i = 0; i < objects.length; i++) {
|
||||
objects[i] = propertyConverter.write(objects[i]);
|
||||
objects[i] = propertyValueConverter.write(objects[i]);
|
||||
}
|
||||
} else {
|
||||
criteriaEntry.setValue(propertyConverter.write(value));
|
||||
criteriaEntry.setValue(propertyValueConverter.write(value));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -21,9 +21,9 @@ import org.springframework.data.mapping.PersistentProperty;
|
||||
* @author Sascha Woo
|
||||
* @since 4.3
|
||||
*/
|
||||
public class NumberRangePersistentPropertyConverter extends AbstractRangePersistentPropertyConverter<Number> {
|
||||
public class NumberRangePropertyValueConverter extends AbstractRangePropertyValueConverter<Number> {
|
||||
|
||||
public NumberRangePersistentPropertyConverter(PersistentProperty<?> property) {
|
||||
public NumberRangePropertyValueConverter(PersistentProperty<?> property) {
|
||||
super(property);
|
||||
}
|
||||
|
@ -26,13 +26,13 @@ import org.springframework.data.mapping.PersistentProperty;
|
||||
* @author Sascha Woo
|
||||
* @since 4.3
|
||||
*/
|
||||
public class TemporalPersistentPropertyConverter extends AbstractPersistentPropertyConverter {
|
||||
public class TemporalPropertyValueConverter extends AbstractPropertyValueConverter {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TemporalPersistentPropertyConverter.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TemporalPropertyValueConverter.class);
|
||||
|
||||
private final List<ElasticsearchDateConverter> dateConverters;
|
||||
|
||||
public TemporalPersistentPropertyConverter(PersistentProperty<?> property,
|
||||
public TemporalPropertyValueConverter(PersistentProperty<?> property,
|
||||
List<ElasticsearchDateConverter> dateConverters) {
|
||||
|
||||
super(property);
|
@ -27,14 +27,13 @@ import org.springframework.util.Assert;
|
||||
* @author Sascha Woo
|
||||
* @since 4.3
|
||||
*/
|
||||
public class TemporalRangePersistentPropertyConverter
|
||||
extends AbstractRangePersistentPropertyConverter<TemporalAccessor> {
|
||||
public class TemporalRangePropertyValueConverter extends AbstractRangePropertyValueConverter<TemporalAccessor> {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TemporalRangePersistentPropertyConverter.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TemporalRangePropertyValueConverter.class);
|
||||
|
||||
private final List<ElasticsearchDateConverter> dateConverters;
|
||||
|
||||
public TemporalRangePersistentPropertyConverter(PersistentProperty<?> property,
|
||||
public TemporalRangePropertyValueConverter(PersistentProperty<?> property,
|
||||
List<ElasticsearchDateConverter> dateConverters) {
|
||||
|
||||
super(property);
|
@ -48,17 +48,17 @@ public interface ElasticsearchPersistentProperty extends PersistentProperty<Elas
|
||||
boolean isSeqNoPrimaryTermProperty();
|
||||
|
||||
/**
|
||||
* @return true if an {@link ElasticsearchPersistentPropertyConverter} is available for this instance.
|
||||
* @return true if an {@link PropertyValueConverter} is available for this instance.
|
||||
* @since 4.0
|
||||
*/
|
||||
boolean hasPropertyConverter();
|
||||
boolean hasPropertyValueConverter();
|
||||
|
||||
/**
|
||||
* @return the {@link ElasticsearchPersistentPropertyConverter} for this instance.
|
||||
* @return the {@link PropertyValueConverter} for this instance.
|
||||
* @since 4.0
|
||||
*/
|
||||
@Nullable
|
||||
ElasticsearchPersistentPropertyConverter getPropertyConverter();
|
||||
PropertyValueConverter getPropertyValueConverter();
|
||||
|
||||
/**
|
||||
* Returns true if the property may be read.
|
||||
|
@ -16,26 +16,26 @@
|
||||
package org.springframework.data.elasticsearch.core.mapping;
|
||||
|
||||
/**
|
||||
* Interface defining methods to convert a persistent property value to an elasticsearch property value and back.
|
||||
* Interface defining methods to convert the value of an entity-property to a value in Elasticsearch and back.
|
||||
*
|
||||
* @author Peter-Josef Meisch
|
||||
* @author Sascha Woo
|
||||
*/
|
||||
public interface ElasticsearchPersistentPropertyConverter {
|
||||
public interface PropertyValueConverter {
|
||||
|
||||
/**
|
||||
* Converts a persistent property value to an elasticsearch property value.
|
||||
* Converts a property value to an elasticsearch value.
|
||||
*
|
||||
* @param value the persistent property value to convert, must not be {@literal null}
|
||||
* @return The elasticsearch property value.
|
||||
* @param value the value to convert, must not be {@literal null}
|
||||
* @return The elasticsearch property value, must not be {@literal null}
|
||||
*/
|
||||
Object write(Object value);
|
||||
|
||||
/**
|
||||
* Converts an elasticsearch property value to a persistent property value.
|
||||
* Converts an elasticsearch property value to a property value.
|
||||
*
|
||||
* @param value the elasticsearch property value to convert, must not be {@literal null}
|
||||
* @return The persistent property value.
|
||||
* @return The converted value, must not be {@literal null}
|
||||
*/
|
||||
Object read(Object value);
|
||||
}
|
@ -23,24 +23,26 @@ import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.data.elasticsearch.annotations.DateFormat;
|
||||
import org.springframework.data.elasticsearch.annotations.Field;
|
||||
import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||
import org.springframework.data.elasticsearch.annotations.GeoPointField;
|
||||
import org.springframework.data.elasticsearch.annotations.GeoShapeField;
|
||||
import org.springframework.data.elasticsearch.annotations.MultiField;
|
||||
import org.springframework.data.elasticsearch.annotations.ValueConverter;
|
||||
import org.springframework.data.elasticsearch.core.Range;
|
||||
import org.springframework.data.elasticsearch.core.suggest.Completion;
|
||||
import org.springframework.data.elasticsearch.core.convert.DatePersistentPropertyConverter;
|
||||
import org.springframework.data.elasticsearch.core.convert.DateRangePersistentPropertyConverter;
|
||||
import org.springframework.data.elasticsearch.core.convert.DatePropertyValueConverter;
|
||||
import org.springframework.data.elasticsearch.core.convert.DateRangePropertyValueConverter;
|
||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchDateConverter;
|
||||
import org.springframework.data.elasticsearch.core.convert.NumberRangePersistentPropertyConverter;
|
||||
import org.springframework.data.elasticsearch.core.convert.TemporalPersistentPropertyConverter;
|
||||
import org.springframework.data.elasticsearch.core.convert.TemporalRangePersistentPropertyConverter;
|
||||
import org.springframework.data.elasticsearch.core.convert.NumberRangePropertyValueConverter;
|
||||
import org.springframework.data.elasticsearch.core.convert.TemporalPropertyValueConverter;
|
||||
import org.springframework.data.elasticsearch.core.convert.TemporalRangePropertyValueConverter;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoJson;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
||||
import org.springframework.data.elasticsearch.core.join.JoinField;
|
||||
import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm;
|
||||
import org.springframework.data.elasticsearch.core.suggest.Completion;
|
||||
import org.springframework.data.mapping.Association;
|
||||
import org.springframework.data.mapping.MappingException;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
@ -75,7 +77,7 @@ public class SimpleElasticsearchPersistentProperty extends
|
||||
private final boolean isId;
|
||||
private final boolean isSeqNoPrimaryTerm;
|
||||
private final @Nullable String annotatedFieldName;
|
||||
@Nullable private ElasticsearchPersistentPropertyConverter propertyConverter;
|
||||
@Nullable private PropertyValueConverter propertyValueConverter;
|
||||
private final boolean storeNullValue;
|
||||
|
||||
public SimpleElasticsearchPersistentProperty(Property property,
|
||||
@ -98,20 +100,20 @@ public class SimpleElasticsearchPersistentProperty extends
|
||||
throw new MappingException("@Field annotation must not be used on a @MultiField property.");
|
||||
}
|
||||
|
||||
initPropertyConverter();
|
||||
initPropertyValueConverter();
|
||||
|
||||
storeNullValue = isField && getRequiredAnnotation(Field.class).storeNullValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPropertyConverter() {
|
||||
return propertyConverter != null;
|
||||
public boolean hasPropertyValueConverter() {
|
||||
return propertyValueConverter != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ElasticsearchPersistentPropertyConverter getPropertyConverter() {
|
||||
return propertyConverter;
|
||||
public PropertyValueConverter getPropertyValueConverter() {
|
||||
return propertyValueConverter;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -136,7 +138,13 @@ public class SimpleElasticsearchPersistentProperty extends
|
||||
/**
|
||||
* Initializes the property converter for this {@link PersistentProperty}, if any.
|
||||
*/
|
||||
private void initPropertyConverter() {
|
||||
private void initPropertyValueConverter() {
|
||||
|
||||
initPropertyValueConverterFromAnnotation();
|
||||
|
||||
if (hasPropertyValueConverter()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Class<?> actualType = getActualTypeOrNull();
|
||||
if (actualType == null) {
|
||||
@ -158,9 +166,9 @@ public class SimpleElasticsearchPersistentProperty extends
|
||||
}
|
||||
|
||||
if (TemporalAccessor.class.isAssignableFrom(actualType)) {
|
||||
propertyConverter = new TemporalPersistentPropertyConverter(this, dateConverters);
|
||||
propertyValueConverter = new TemporalPropertyValueConverter(this, dateConverters);
|
||||
} else if (Date.class.isAssignableFrom(actualType)) {
|
||||
propertyConverter = new DatePersistentPropertyConverter(this, dateConverters);
|
||||
propertyValueConverter = new DatePropertyValueConverter(this, dateConverters);
|
||||
} else {
|
||||
LOGGER.warn("Unsupported type '{}' for date property '{}'.", actualType, getName());
|
||||
}
|
||||
@ -179,9 +187,9 @@ public class SimpleElasticsearchPersistentProperty extends
|
||||
|
||||
Class<?> genericType = getTypeInformation().getTypeArguments().get(0).getType();
|
||||
if (TemporalAccessor.class.isAssignableFrom(genericType)) {
|
||||
propertyConverter = new TemporalRangePersistentPropertyConverter(this, dateConverters);
|
||||
propertyValueConverter = new TemporalRangePropertyValueConverter(this, dateConverters);
|
||||
} else if (Date.class.isAssignableFrom(genericType)) {
|
||||
propertyConverter = new DateRangePersistentPropertyConverter(this, dateConverters);
|
||||
propertyValueConverter = new DateRangePropertyValueConverter(this, dateConverters);
|
||||
} else {
|
||||
LOGGER.warn("Unsupported generic type '{}' for date range property '{}'.", genericType, getName());
|
||||
}
|
||||
@ -205,7 +213,7 @@ public class SimpleElasticsearchPersistentProperty extends
|
||||
return;
|
||||
}
|
||||
|
||||
propertyConverter = new NumberRangePersistentPropertyConverter(this);
|
||||
propertyValueConverter = new NumberRangePropertyValueConverter(this);
|
||||
break;
|
||||
}
|
||||
case Ip_Range: {
|
||||
@ -216,6 +224,26 @@ public class SimpleElasticsearchPersistentProperty extends
|
||||
}
|
||||
}
|
||||
|
||||
private void initPropertyValueConverterFromAnnotation() {
|
||||
|
||||
ValueConverter annotation = findAnnotation(ValueConverter.class);
|
||||
|
||||
if (annotation != null) {
|
||||
Class<? extends PropertyValueConverter> clazz = annotation.value();
|
||||
|
||||
if (Enum.class.isAssignableFrom(clazz)) {
|
||||
PropertyValueConverter[] enumConstants = clazz.getEnumConstants();
|
||||
|
||||
if (enumConstants == null || enumConstants.length != 1) {
|
||||
throw new IllegalArgumentException(clazz + " is an enum with more than 1 constant and cannot be used here");
|
||||
}
|
||||
propertyValueConverter = enumConstants[0];
|
||||
} else {
|
||||
propertyValueConverter = BeanUtils.instantiateClass(clazz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<ElasticsearchDateConverter> getDateConverters(Field field, Class<?> actualType) {
|
||||
|
||||
DateFormat[] dateFormats = field.format();
|
||||
|
@ -26,14 +26,11 @@ import org.junit.jupiter.api.Test;
|
||||
* @author Sascha Woo
|
||||
* @since 4.3
|
||||
*/
|
||||
public class RangeTests {
|
||||
public class RangeUnitTests {
|
||||
|
||||
@Test
|
||||
public void shouldContainsLocalDate() {
|
||||
|
||||
// given
|
||||
// when
|
||||
// then
|
||||
assertThat(Range.open(LocalDate.of(2021, 1, 1), LocalDate.of(2021, 2, 1)).contains(LocalDate.of(2021, 1, 10)))
|
||||
.isTrue();
|
||||
}
|
||||
@ -41,21 +38,17 @@ public class RangeTests {
|
||||
@Test
|
||||
public void shouldEqualToSameRange() {
|
||||
|
||||
// given
|
||||
Range<LocalDate> range1 = Range.open(LocalDate.of(2021, 1, 1), LocalDate.of(2021, 2, 1));
|
||||
Range<LocalDate> range2 = Range.open(LocalDate.of(2021, 1, 1), LocalDate.of(2021, 2, 1));
|
||||
// when
|
||||
// then
|
||||
|
||||
assertThat(range1).isEqualTo(range2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHaveClosedBoundaries() {
|
||||
|
||||
// given
|
||||
Range<Integer> range = Range.closed(1, 3);
|
||||
// when
|
||||
// then
|
||||
|
||||
assertThat(range.contains(1)).isTrue();
|
||||
assertThat(range.contains(2)).isTrue();
|
||||
assertThat(range.contains(3)).isTrue();
|
||||
@ -64,10 +57,8 @@ public class RangeTests {
|
||||
@Test
|
||||
public void shouldHaveJustOneValue() {
|
||||
|
||||
// given
|
||||
Range<Integer> range = Range.just(2);
|
||||
// when
|
||||
// then
|
||||
|
||||
assertThat(range.contains(1)).isFalse();
|
||||
assertThat(range.contains(2)).isTrue();
|
||||
assertThat(range.contains(3)).isFalse();
|
||||
@ -76,10 +67,8 @@ public class RangeTests {
|
||||
@Test
|
||||
public void shouldHaveLeftOpenBoundary() {
|
||||
|
||||
// given
|
||||
Range<Integer> range = Range.leftOpen(1, 3);
|
||||
// when
|
||||
// then
|
||||
|
||||
assertThat(range.contains(1)).isFalse();
|
||||
assertThat(range.contains(2)).isTrue();
|
||||
assertThat(range.contains(3)).isTrue();
|
||||
@ -88,10 +77,8 @@ public class RangeTests {
|
||||
@Test
|
||||
public void shouldHaveLeftUnboundedAndRightExclusive() {
|
||||
|
||||
// given
|
||||
Range<Integer> range = Range.leftUnbounded(Range.Bound.exclusive(3));
|
||||
// when
|
||||
// then
|
||||
|
||||
assertThat(range.contains(0)).isTrue();
|
||||
assertThat(range.contains(1)).isTrue();
|
||||
assertThat(range.contains(2)).isTrue();
|
||||
@ -101,10 +88,8 @@ public class RangeTests {
|
||||
@Test
|
||||
public void shouldHaveLeftUnboundedAndRightInclusive() {
|
||||
|
||||
// given
|
||||
Range<Integer> range = Range.leftUnbounded(Range.Bound.inclusive(3));
|
||||
// when
|
||||
// then
|
||||
|
||||
assertThat(range.contains(0)).isTrue();
|
||||
assertThat(range.contains(1)).isTrue();
|
||||
assertThat(range.contains(2)).isTrue();
|
||||
@ -114,10 +99,8 @@ public class RangeTests {
|
||||
@Test
|
||||
public void shouldHaveOpenBoundaries() {
|
||||
|
||||
// given
|
||||
Range<Integer> range = Range.open(1, 3);
|
||||
// when
|
||||
// then
|
||||
|
||||
assertThat(range.contains(1)).isFalse();
|
||||
assertThat(range.contains(2)).isTrue();
|
||||
assertThat(range.contains(3)).isFalse();
|
||||
@ -126,10 +109,8 @@ public class RangeTests {
|
||||
@Test
|
||||
public void shouldHaveRightOpenBoundary() {
|
||||
|
||||
// given
|
||||
Range<Integer> range = Range.rightOpen(1, 3);
|
||||
// when
|
||||
// then
|
||||
|
||||
assertThat(range.contains(1)).isTrue();
|
||||
assertThat(range.contains(2)).isTrue();
|
||||
assertThat(range.contains(3)).isFalse();
|
||||
@ -138,10 +119,8 @@ public class RangeTests {
|
||||
@Test
|
||||
public void shouldHaveRightUnboundedAndLeftExclusive() {
|
||||
|
||||
// given
|
||||
Range<Integer> range = Range.rightUnbounded(Range.Bound.exclusive(1));
|
||||
// when
|
||||
// then
|
||||
|
||||
assertThat(range.contains(1)).isFalse();
|
||||
assertThat(range.contains(2)).isTrue();
|
||||
assertThat(range.contains(3)).isTrue();
|
||||
@ -151,10 +130,8 @@ public class RangeTests {
|
||||
@Test
|
||||
public void shouldHaveRightUnboundedAndLeftInclusive() {
|
||||
|
||||
// given
|
||||
Range<Integer> range = Range.rightUnbounded(Range.Bound.inclusive(1));
|
||||
// when
|
||||
// then
|
||||
|
||||
assertThat(range.contains(1)).isTrue();
|
||||
assertThat(range.contains(2)).isTrue();
|
||||
assertThat(range.contains(3)).isTrue();
|
||||
@ -164,12 +141,7 @@ public class RangeTests {
|
||||
@Test
|
||||
public void shouldThrowExceptionIfNotComparable() {
|
||||
|
||||
// given
|
||||
// when
|
||||
Throwable thrown = catchThrowable(() -> Range.just(Collections.singletonList("test")));
|
||||
// then
|
||||
assertThat(thrown).isInstanceOf(IllegalArgumentException.class)
|
||||
assertThatThrownBy(() -> Range.just(Collections.singletonList("test"))).isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessageContaining("value must implements Comparable!");
|
||||
}
|
||||
|
||||
}
|
@ -52,6 +52,7 @@ import org.springframework.data.elasticsearch.annotations.DateFormat;
|
||||
import org.springframework.data.elasticsearch.annotations.Field;
|
||||
import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||
import org.springframework.data.elasticsearch.annotations.GeoPointField;
|
||||
import org.springframework.data.elasticsearch.annotations.ValueConverter;
|
||||
import org.springframework.data.elasticsearch.core.Range;
|
||||
import org.springframework.data.elasticsearch.core.document.Document;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoJsonEntity;
|
||||
@ -63,6 +64,7 @@ import org.springframework.data.elasticsearch.core.geo.GeoJsonMultiPolygon;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoJsonPoint;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoJsonPolygon;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
||||
import org.springframework.data.elasticsearch.core.mapping.PropertyValueConverter;
|
||||
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
||||
import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm;
|
||||
import org.springframework.data.geo.Box;
|
||||
@ -71,6 +73,7 @@ import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.geo.Polygon;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MappingElasticsearchConverter}.
|
||||
@ -1446,6 +1449,53 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
assertEquals(expected, document.toJson(), true);
|
||||
}
|
||||
|
||||
@Test // #1945
|
||||
@DisplayName("should write using ValueConverters")
|
||||
void shouldWriteUsingValueConverters() throws JSONException {
|
||||
|
||||
EntityWithCustomValueConverters entity = new EntityWithCustomValueConverters();
|
||||
entity.setId("42");
|
||||
entity.setFieldWithClassBasedConverter("classbased");
|
||||
entity.setFieldWithEnumBasedConverter("enumbased");
|
||||
entity.setDontConvert("Monty Python's Flying Circus");
|
||||
|
||||
String expected = "{\n" + //
|
||||
" \"id\": \"42\",\n" + //
|
||||
" \"fieldWithClassBasedConverter\": \"desabssalc\",\n" + //
|
||||
" \"fieldWithEnumBasedConverter\": \"desabmune\",\n" + //
|
||||
" \"dontConvert\": \"Monty Python's Flying Circus\"\n" + //
|
||||
"}\n"; //
|
||||
|
||||
Document document = Document.create();
|
||||
|
||||
mappingElasticsearchConverter.write(entity, document);
|
||||
|
||||
assertEquals(expected, document.toJson(), false);
|
||||
}
|
||||
|
||||
@Test // #1945
|
||||
@DisplayName("should read using ValueConverters")
|
||||
void shouldReadUsingValueConverters() throws JSONException {
|
||||
|
||||
String json = "{\n" + //
|
||||
" \"id\": \"42\",\n" + //
|
||||
" \"fieldWithClassBasedConverter\": \"desabssalc\",\n" + //
|
||||
" \"fieldWithEnumBasedConverter\": \"desabmune\",\n" + //
|
||||
" \"dontConvert\": \"Monty Python's Flying Circus\"\n" + //
|
||||
"}\n"; //
|
||||
|
||||
Document source = Document.parse(json);
|
||||
|
||||
// when
|
||||
EntityWithCustomValueConverters entity = mappingElasticsearchConverter.read(EntityWithCustomValueConverters.class,
|
||||
source);
|
||||
|
||||
assertThat(entity.getId()).isEqualTo("42");
|
||||
assertThat(entity.getFieldWithClassBasedConverter()).isEqualTo("classbased");
|
||||
assertThat(entity.getFieldWithEnumBasedConverter()).isEqualTo("enumbased");
|
||||
assertThat(entity.getDontConvert()).isEqualTo("Monty Python's Flying Circus");
|
||||
}
|
||||
|
||||
private Map<String, Object> writeToMap(Object source) {
|
||||
|
||||
Document sink = Document.create();
|
||||
@ -2309,5 +2359,82 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
this.cars = cars;
|
||||
}
|
||||
}
|
||||
|
||||
private static class EntityWithCustomValueConverters {
|
||||
@Nullable @Id private String id;
|
||||
@Nullable @ValueConverter(ClassBasedValueConverter.class) private String fieldWithClassBasedConverter;
|
||||
@Nullable @ValueConverter(EnumBasedValueConverter.class) private String fieldWithEnumBasedConverter;
|
||||
@Nullable private String dontConvert;
|
||||
|
||||
@Nullable
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(@Nullable String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getFieldWithClassBasedConverter() {
|
||||
return fieldWithClassBasedConverter;
|
||||
}
|
||||
|
||||
public void setFieldWithClassBasedConverter(@Nullable String fieldWithClassBasedConverter) {
|
||||
this.fieldWithClassBasedConverter = fieldWithClassBasedConverter;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getFieldWithEnumBasedConverter() {
|
||||
return fieldWithEnumBasedConverter;
|
||||
}
|
||||
|
||||
public void setFieldWithEnumBasedConverter(@Nullable String fieldWithEnumBasedConverter) {
|
||||
this.fieldWithEnumBasedConverter = fieldWithEnumBasedConverter;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getDontConvert() {
|
||||
return dontConvert;
|
||||
}
|
||||
|
||||
public void setDontConvert(@Nullable String dontConvert) {
|
||||
this.dontConvert = dontConvert;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ClassBasedValueConverter implements PropertyValueConverter {
|
||||
|
||||
@Override
|
||||
public Object write(Object value) {
|
||||
return reverse(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object read(Object value) {
|
||||
return reverse(value);
|
||||
}
|
||||
}
|
||||
|
||||
private enum EnumBasedValueConverter implements PropertyValueConverter {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public Object write(Object value) {
|
||||
return reverse(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object read(Object value) {
|
||||
return reverse(value);
|
||||
}
|
||||
}
|
||||
|
||||
private static String reverse(Object o) {
|
||||
|
||||
Assert.notNull(o, "o must not be null");
|
||||
|
||||
return new StringBuilder().append(o.toString()).reverse().toString();
|
||||
}
|
||||
// endregion
|
||||
}
|
||||
|
@ -27,11 +27,13 @@ import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.elasticsearch.annotations.DateFormat;
|
||||
import org.springframework.data.elasticsearch.annotations.Field;
|
||||
import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||
import org.springframework.data.elasticsearch.annotations.InnerField;
|
||||
import org.springframework.data.elasticsearch.annotations.MultiField;
|
||||
import org.springframework.data.elasticsearch.annotations.ValueConverter;
|
||||
import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm;
|
||||
import org.springframework.data.mapping.MappingException;
|
||||
import org.springframework.data.mapping.model.FieldNamingStrategy;
|
||||
@ -92,20 +94,20 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
|
||||
SimpleElasticsearchPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class);
|
||||
|
||||
ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("localDate");
|
||||
assertThat(persistentProperty.hasPropertyConverter()).isTrue();
|
||||
assertThat(persistentProperty.getPropertyConverter()).isNotNull();
|
||||
assertThat(persistentProperty.hasPropertyValueConverter()).isTrue();
|
||||
assertThat(persistentProperty.getPropertyValueConverter()).isNotNull();
|
||||
|
||||
persistentProperty = persistentEntity.getRequiredPersistentProperty("localDateTime");
|
||||
assertThat(persistentProperty.hasPropertyConverter()).isTrue();
|
||||
assertThat(persistentProperty.getPropertyConverter()).isNotNull();
|
||||
assertThat(persistentProperty.hasPropertyValueConverter()).isTrue();
|
||||
assertThat(persistentProperty.getPropertyValueConverter()).isNotNull();
|
||||
|
||||
persistentProperty = persistentEntity.getRequiredPersistentProperty("legacyDate");
|
||||
assertThat(persistentProperty.hasPropertyConverter()).isTrue();
|
||||
assertThat(persistentProperty.getPropertyConverter()).isNotNull();
|
||||
assertThat(persistentProperty.hasPropertyValueConverter()).isTrue();
|
||||
assertThat(persistentProperty.getPropertyValueConverter()).isNotNull();
|
||||
|
||||
persistentProperty = persistentEntity.getRequiredPersistentProperty("localDateList");
|
||||
assertThat(persistentProperty.hasPropertyConverter()).isTrue();
|
||||
assertThat(persistentProperty.getPropertyConverter()).isNotNull();
|
||||
assertThat(persistentProperty.hasPropertyValueConverter()).isTrue();
|
||||
assertThat(persistentProperty.getPropertyValueConverter()).isNotNull();
|
||||
}
|
||||
|
||||
@Test // DATAES-716
|
||||
@ -114,7 +116,7 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
|
||||
ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("localDate");
|
||||
LocalDate localDate = LocalDate.of(2019, 12, 27);
|
||||
|
||||
String converted = persistentProperty.getPropertyConverter().write(localDate).toString();
|
||||
String converted = persistentProperty.getPropertyValueConverter().write(localDate).toString();
|
||||
|
||||
assertThat(converted).isEqualTo("27.12.2019");
|
||||
}
|
||||
@ -124,7 +126,7 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
|
||||
SimpleElasticsearchPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class);
|
||||
ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("localDate");
|
||||
|
||||
Object converted = persistentProperty.getPropertyConverter().read("27.12.2019");
|
||||
Object converted = persistentProperty.getPropertyValueConverter().read("27.12.2019");
|
||||
|
||||
assertThat(converted).isInstanceOf(LocalDate.class);
|
||||
assertThat(converted).isEqualTo(LocalDate.of(2019, 12, 27));
|
||||
@ -138,7 +140,7 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
|
||||
.from(ZonedDateTime.of(LocalDateTime.of(2020, 4, 19, 19, 44), ZoneId.of("UTC")));
|
||||
Date legacyDate = calendar.getTime();
|
||||
|
||||
String converted = persistentProperty.getPropertyConverter().write(legacyDate).toString();
|
||||
String converted = persistentProperty.getPropertyValueConverter().write(legacyDate).toString();
|
||||
|
||||
assertThat(converted).isEqualTo("20200419T194400.000Z");
|
||||
}
|
||||
@ -148,7 +150,7 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
|
||||
SimpleElasticsearchPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class);
|
||||
ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("legacyDate");
|
||||
|
||||
Object converted = persistentProperty.getPropertyConverter().read("20200419T194400.000Z");
|
||||
Object converted = persistentProperty.getPropertyValueConverter().read("20200419T194400.000Z");
|
||||
|
||||
assertThat(converted).isInstanceOf(Date.class);
|
||||
GregorianCalendar calendar = GregorianCalendar
|
||||
@ -246,6 +248,21 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
|
||||
assertThat(property.getFieldName()).isEqualTo("CUStomFIEldnAME");
|
||||
}
|
||||
|
||||
@Test // #1945
|
||||
@DisplayName("should use ValueConverter annotation")
|
||||
void shouldUseValueConverterAnnotation() {
|
||||
|
||||
SimpleElasticsearchPersistentEntity<?> persistentEntity = context
|
||||
.getRequiredPersistentEntity(EntityWithCustomValueConverters.class);
|
||||
|
||||
assertThat(
|
||||
persistentEntity.getRequiredPersistentProperty("fieldWithClassBasedConverter").getPropertyValueConverter())
|
||||
.isInstanceOf(ClassBasedValueConverter.class);
|
||||
assertThat(
|
||||
persistentEntity.getRequiredPersistentProperty("fieldWithEnumBasedConverter").getPropertyValueConverter())
|
||||
.isInstanceOf(EnumBasedValueConverter.class);
|
||||
}
|
||||
|
||||
// region entities
|
||||
static class FieldNameProperty {
|
||||
@Nullable @Field(name = "by-name") String fieldProperty;
|
||||
@ -324,5 +341,38 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
|
||||
this.withCustomFieldName = withCustomFieldName;
|
||||
}
|
||||
}
|
||||
|
||||
private static class EntityWithCustomValueConverters {
|
||||
@Id private String id;
|
||||
@Nullable @ValueConverter(ClassBasedValueConverter.class) private String fieldWithClassBasedConverter;
|
||||
@Nullable @ValueConverter(EnumBasedValueConverter.class) private String fieldWithEnumBasedConverter;
|
||||
}
|
||||
|
||||
private static class ClassBasedValueConverter implements PropertyValueConverter {
|
||||
|
||||
@Override
|
||||
public Object write(Object value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object read(Object value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private enum EnumBasedValueConverter implements PropertyValueConverter {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public Object write(Object value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object read(Object value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
// endregion
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user