mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-06-17 09:32:11 +00:00
DATAES-828 - Fields of type date need to have a format defined.
Original PR: #457
This commit is contained in:
parent
68ce0c2184
commit
1cee4057d9
@ -43,7 +43,7 @@ The following annotations are available:
|
|||||||
* `@Field`: Applied at the field level and defines properties of the field, most of the attributes map to the respective https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html[Elasticsearch Mapping] definitions (the following list is not complete, check the annotation Javadoc for a complete reference):
|
* `@Field`: Applied at the field level and defines properties of the field, most of the attributes map to the respective https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html[Elasticsearch Mapping] definitions (the following list is not complete, check the annotation Javadoc for a complete reference):
|
||||||
** `name`: The name of the field as it will be represented in the Elasticsearch document, if not set, the Java field name is used.
|
** `name`: The name of the field as it will be represented in the Elasticsearch document, if not set, the Java field name is used.
|
||||||
** `type`: the field type, can be one of _Text, Keyword, Long, Integer, Short, Byte, Double, Float, Half_Float, Scaled_Float, Date, Date_Nanos, Boolean, Binary, Integer_Range, Float_Range, Long_Range, Double_Range, Date_Range, Ip_Range, Object, Nested, Ip, TokenCount, Percolator, Flattened, Search_As_You_Type_. See https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html[Elasticsearch Mapping Types]
|
** `type`: the field type, can be one of _Text, Keyword, Long, Integer, Short, Byte, Double, Float, Half_Float, Scaled_Float, Date, Date_Nanos, Boolean, Binary, Integer_Range, Float_Range, Long_Range, Double_Range, Date_Range, Ip_Range, Object, Nested, Ip, TokenCount, Percolator, Flattened, Search_As_You_Type_. See https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html[Elasticsearch Mapping Types]
|
||||||
** `format` and `pattern` custom definitions for the _Date_ type.
|
** `format` and `pattern` definitions for the _Date_ type. `format` must be defined for date types.
|
||||||
** `store`: Flag wether the original field value should be store in Elasticsearch, default value is _false_.
|
** `store`: Flag wether the original field value should be store in Elasticsearch, default value is _false_.
|
||||||
** `analyzer`, `searchAnalyzer`, `normalizer` for specifying custom custom analyzers and normalizer.
|
** `analyzer`, `searchAnalyzer`, `normalizer` for specifying custom 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.
|
* `@GeoPoint`: marks a field as _geo_point_ datatype. Can be omitted if the field is an instance of the `GeoPoint` class.
|
||||||
|
@ -117,9 +117,15 @@ public class SimpleElasticsearchPersistentProperty extends
|
|||||||
boolean isTemporalAccessor = TemporalAccessor.class.isAssignableFrom(getType());
|
boolean isTemporalAccessor = TemporalAccessor.class.isAssignableFrom(getType());
|
||||||
boolean isDate = Date.class.isAssignableFrom(getType());
|
boolean isDate = Date.class.isAssignableFrom(getType());
|
||||||
|
|
||||||
if (field != null && field.type() == FieldType.Date && (isTemporalAccessor || isDate)) {
|
if (field != null && (field.type() == FieldType.Date || field.type() == FieldType.Date_Nanos)
|
||||||
|
&& (isTemporalAccessor || isDate)) {
|
||||||
DateFormat dateFormat = field.format();
|
DateFormat dateFormat = field.format();
|
||||||
|
|
||||||
|
if (dateFormat == DateFormat.none) {
|
||||||
|
throw new MappingException(String.format("property %s is annotated with FieldType.%s but has no DateFormat defined",
|
||||||
|
getName(), field.type().name()));
|
||||||
|
}
|
||||||
|
|
||||||
ElasticsearchDateConverter converter = null;
|
ElasticsearchDateConverter converter = null;
|
||||||
|
|
||||||
if (dateFormat == DateFormat.custom) {
|
if (dateFormat == DateFormat.custom) {
|
||||||
|
@ -34,6 +34,7 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.data.annotation.Id;
|
import org.springframework.data.annotation.Id;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.DateFormat;
|
||||||
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.Field;
|
||||||
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
|
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
|
||||||
@ -146,7 +147,7 @@ public class LogEntityTests {
|
|||||||
|
|
||||||
@Field(type = Ip) private String ip;
|
@Field(type = Ip) private String ip;
|
||||||
|
|
||||||
@Field(type = Date) private java.util.Date date;
|
@Field(type = Date, format = DateFormat.date_time) private java.util.Date date;
|
||||||
|
|
||||||
private LogEntity() {}
|
private LogEntity() {}
|
||||||
|
|
||||||
|
@ -859,7 +859,7 @@ public class MappingBuilderTests extends MappingContextBaseTests {
|
|||||||
|
|
||||||
@Nullable @Id private String id;
|
@Nullable @Id private String id;
|
||||||
|
|
||||||
@Nullable @Field(type = FieldType.Date, index = false) private Date createdDate;
|
@Nullable @Field(type = FieldType.Date, format = DateFormat.date_time, index = false) private Date createdDate;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
@ -41,10 +41,10 @@ public class SimpleElasticsearchDateMappingTests extends MappingContextBaseTests
|
|||||||
|
|
||||||
private static final String EXPECTED_MAPPING = "{\"properties\":{\"message\":{\"store\":true,"
|
private static final String EXPECTED_MAPPING = "{\"properties\":{\"message\":{\"store\":true,"
|
||||||
+ "\"type\":\"text\",\"index\":false,\"analyzer\":\"standard\"},\"customFormatDate\":{\"type\":\"date\",\"format\":\"dd.MM.uuuu hh:mm\"},"
|
+ "\"type\":\"text\",\"index\":false,\"analyzer\":\"standard\"},\"customFormatDate\":{\"type\":\"date\",\"format\":\"dd.MM.uuuu hh:mm\"},"
|
||||||
+ "\"defaultFormatDate\":{\"type\":\"date\"},\"basicFormatDate\":{\""
|
+ "\"basicFormatDate\":{\""
|
||||||
+ "type\":\"date\",\"format\":\"basic_date\"}}}";
|
+ "type\":\"date\",\"format\":\"basic_date\"}}}";
|
||||||
|
|
||||||
@Test // DATAES-568
|
@Test // DATAES-568, DATAES-828
|
||||||
public void testCorrectDateMappings() {
|
public void testCorrectDateMappings() {
|
||||||
|
|
||||||
String mapping = getMappingBuilder().buildPropertyMapping(SampleDateMappingEntity.class);
|
String mapping = getMappingBuilder().buildPropertyMapping(SampleDateMappingEntity.class);
|
||||||
@ -67,8 +67,6 @@ public class SimpleElasticsearchDateMappingTests extends MappingContextBaseTests
|
|||||||
@Field(type = Date, format = DateFormat.custom,
|
@Field(type = Date, format = DateFormat.custom,
|
||||||
pattern = "dd.MM.uuuu hh:mm") private LocalDateTime customFormatDate;
|
pattern = "dd.MM.uuuu hh:mm") private LocalDateTime customFormatDate;
|
||||||
|
|
||||||
@Field(type = FieldType.Date) private LocalDateTime defaultFormatDate;
|
|
||||||
|
|
||||||
@Field(type = FieldType.Date, format = DateFormat.basic_date) private LocalDateTime basicFormatDate;
|
@Field(type = FieldType.Date, format = DateFormat.basic_date) private LocalDateTime basicFormatDate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,6 +173,20 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
|
|||||||
assertThat(seqNoProperty.isReadable()).isFalse();
|
assertThat(seqNoProperty.isReadable()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // DATAES-828
|
||||||
|
void shouldRequireFormatForDateField() {
|
||||||
|
assertThatExceptionOfType(MappingException.class) //
|
||||||
|
.isThrownBy(() -> context.getRequiredPersistentEntity(DateFieldWithNoFormat.class)) //
|
||||||
|
.withMessageContaining("date");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // DATAES-828
|
||||||
|
void shouldRequireFormatForDateNanosField() {
|
||||||
|
assertThatExceptionOfType(MappingException.class) //
|
||||||
|
.isThrownBy(() -> context.getRequiredPersistentEntity(DateNanosFieldWithNoFormat.class)) //
|
||||||
|
.withMessageContaining("date");
|
||||||
|
}
|
||||||
|
|
||||||
static class InvalidScoreProperty {
|
static class InvalidScoreProperty {
|
||||||
@Nullable @Score String scoreProperty;
|
@Nullable @Score String scoreProperty;
|
||||||
}
|
}
|
||||||
@ -195,4 +209,12 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
|
|||||||
SeqNoPrimaryTerm seqNoPrimaryTerm;
|
SeqNoPrimaryTerm seqNoPrimaryTerm;
|
||||||
String string;
|
String string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class DateFieldWithNoFormat {
|
||||||
|
@Field(type = FieldType.Date) LocalDateTime datetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class DateNanosFieldWithNoFormat {
|
||||||
|
@Field(type = FieldType.Date_Nanos) LocalDateTime datetime;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user