Reputation: 41
My entity has a ZonedDatetime
field
@Indexed
@Entity
public class Book {
@Id
private Long id;
@Field
@DateBridge(resolution = Resolution.SECOND)
private ZonedDateTime createdAt;
// Other fields and setters & getters
}
when I try to save the entity, application throws below exception
field bridge: TwoWayString2FieldBridgeAdaptor [stringBridge=org.hibernate.search.elasticsearch.bridge.builtin.time.impl.ElasticsearchZonedDateTimeBridge@1bec1730]
at
Here are the two-unit tests that I tried where I can reproduce the issue.
If I create a zoned date time ZoneId.of("UTC")
then its good with elastic search bridge
@Test
public void testObjectToString_withZoneId() {
Date date = new Date();
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(date.toInstant(), ZoneId.of("UTC"));
try {
//this is good
ElasticsearchZonedDateTimeBridge.INSTANCE.objectToString(zonedDateTime);
} catch (DateTimeException e) {
Assert.fail(e.getMessage());
}
}
But it fails with below code
@Test
public void testObjectToString_withZonedOffset() {
Date date = new Date();
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(date.toInstant(), ZoneOffset.UTC);
try {
//this throws exception
ElasticsearchZonedDateTimeBridge.INSTANCE.objectToString(zonedDateTime);
} catch (DateTimeException e) {
// Unable to extract value: class java.time.ZonedDateTime
Assert.fail(e.getMessage());
}
}
Hibernate versions that I use are,
hibernate-search-elasticsearch, hibernate-search-orm = 5.11.4.Final
Here is my full stack trace
Caused by: org.hibernate.search.bridge.BridgeException: Exception while calling bridge#set
entity class: com.x.x.x.x.Book
entity property path: expectedDepartureTime
document field name: expectedDepartureTime
field bridge: TwoWayString2FieldBridgeAdaptor [stringBridge=org.hibernate.search.elasticsearch.bridge.builtin.time.impl.ElasticsearchZonedDateTimeBridge@1bec1730]
at org.hibernate.search.bridge.util.impl.ContextualExceptionBridgeHelper.buildBridgeException(ContextualExceptionBridgeHelper.java:104) ~[hibernate-search-engine-5.11.3.Final.jar:5.11.3.Final]
at org.hibernate.search.bridge.util.impl.ContextualExceptionBridgeHelper$OneWayConversionContextImpl.set(ContextualExceptionBridgeHelper.java:138) ~[hibernate-search-engine-5.11.3.Final.jar:5.11.3.Final]
at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.buildDocumentFieldsForProperties(DocumentBuilderIndexedEntity.java:669) ~[hibernate-search-engine-5.11.3.Final.jar:5.11.3.Final]
at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.buildDocumentFields(DocumentBuilderIndexedEntity.java:466) ~[hibernate-search-engine-5.11.3.Final.jar:5.11.3.Final]
at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.getDocument(DocumentBuilderIndexedEntity.java:402) ~[hibernate-search-engine-5.11.3.Final.jar:5.11.3.Final]
at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.createUpdateWork(DocumentBuilderIndexedEntity.java:312) ~[hibernate-search-engine-5.11.3.Final.jar:5.11.3.Final]
....
... 151 more
Caused by: java.time.DateTimeException: Unable to extract value: class java.time.ZonedDateTime
at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:282) ~[?:1.8.0_222]
at java.time.format.DateTimeFormatterBuilder$ZoneIdPrinterParser.format(DateTimeFormatterBuilder.java:3787) ~[?:1.8.0_222]
at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2190) ~[?:1.8.0_222]
at java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1746) ~[?:1.8.0_222]
at java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1720) ~[?:1.8.0_222]
at org.hibernate.search.elasticsearch.bridge.builtin.time.impl.ElasticsearchTemporalAccessorStringBridge.format(ElasticsearchTemporalAccessorStringBridge.java:75) ~[hibernate-search-elasticsearch-5.11.3.Final.jar:5.11.3.Final]
at org.hibernate.search.elasticsearch.bridge.builtin.time.impl.ElasticsearchTemporalAccessorStringBridge.objectToString(ElasticsearchTemporalAccessorStringBridge.java:56) ~[hibernate-search-elasticsearch-5.11.3.Final.jar:5.11.3.Final]
at org.hibernate.search.bridge.util.impl.String2FieldBridgeAdaptor.set(String2FieldBridgeAdaptor.java:31) ~[hibernate-search-engine-5.11.3.Final.jar:5.11.3.Final]
at org.hibernate.search.bridge.util.impl.ContextualExceptionBridgeHelper$OneWayConversionContextImpl.set(ContextualExceptionBridgeHelper.java:135) ~[hibernate-search-engine-5.11.3.Final.jar:5.11.3.Final]
at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.buildDocumentFieldsForProperties(DocumentBuilderIndexedEntity.java:669) ~[hibernate-search-engine-5.11.3.Final.jar:5.11.3.Final]
at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.buildDocumentFields(DocumentBuilderIndexedEntity.java:466) ~[hibernate-search-engine-5.11.3.Final.jar:5.11.3.Final]
at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.getDocument(DocumentBuilderIndexedEntity.java:402) ~[hibernate-search-engine-5.11.3.Final.jar:5.11.3.Final]
at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.createUpdateWork(DocumentBuilderIndexedEntity.java:312) ~[hibernate-search-engine-5.11.3.Final.jar:5.11.3.Final]
at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.addWorkToQueue(DocumentBuilderIndexedEntity.java:254) ~[hibernate-search-engine-5.11.3.Final.jar:5.11.3.Final]
at org.hibernate.search.engine.impl.WorkPlan$PerEntityWork.enqueueLuceneWork(WorkPlan.java:560) ~[hibernate-search-engine-5.11.3.Final.jar:5.11.3.Final]
Upvotes: 3
Views: 336
Reputation: 9977
A ZoneOffset
is a ZoneId
, so this code is correct:
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(date.toInstant(), ZoneOffset.UTC);
However, Hibernate Search uses a very specific format when serializing zoned date times to JSON. That format requires that an actual region ID be present (not just an offset).
That can be considered as a bug, and you're welcome to open a bug report, but I'm afraid that's not the only problem. Even if this problem was fixed in Search 5, in order to successfully index such a value, we would still need to backport a fix for HSEARCH-3548, which as far as I understand requires backward-incompatible changes to the Elasticsearch mapping generated by Hibernate Search. So I'm not sure this is something that can actually be fixed in 5.11.
Elasticsearch support in Hibernate Search 5 is experimental. If you can, you'll have a much better time upgrading to Hibernate Search 6 (still in beta) which provides first-class support for Elasticsearch 5.6 to 7.x, and which actually has a test for your specific problem (and it works correctly). The APIs in Hibernate Search 6 are different, however.
Upvotes: 1