我的实体有一个 ZonedDatetime
字段
@Indexed
@Entity
public class Book {
@Id
private Long id;
@Field
@DateBridge(resolution = Resolution.SECOND)
private ZonedDateTime createdAt;
// Other fields and setters & getters
}
当我尝试保存实体时,应用程序抛出以下异常
field bridge: TwoWayString2FieldBridgeAdaptor [stringBridge=org.hibernate.search.elasticsearch.bridge.builtin.time.impl.ElasticsearchZonedDateTimeBridge@1bec1730]
at
这是我尝试过的两个单元测试,可以重现该问题。
如果我创建分区日期时间ZoneId.of("UTC")
,那么它适合 Elasticsearch 桥
@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());
}
}
但它失败并显示以下代码
@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 版本是,
hibernate-search-elasticsearch, hibernate-search-orm = 5.11.4.Final
这是我的完整堆栈跟踪
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]
最佳答案
ZoneOffset
是 ZoneId
,因此此代码是正确的:
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(date.toInstant(), ZoneOffset.UTC);
但是,Hibernate Search 在将分区日期时间序列化为 JSON 时使用非常特定的格式。该格式要求存在实际的区域 ID(而不仅仅是偏移量)。
这可以被视为一个错误,欢迎您打开错误报告,但恐怕这不是唯一的问题。即使这个问题在 Search 5 中得到了修复,为了成功索引这样的值,我们仍然需要反向移植 HSEARCH-3548 的修复程序。 ,据我了解,这需要对 Hibernate Search 生成的 Elasticsearch 映射进行向后不兼容的更改。所以我不确定这是否真的可以在 5.11 中修复。
Hibernate Search 5 中的 Elasticsearch 支持处于实验阶段。如果可以的话,您将有更好的时间升级到 Hibernate Search 6(仍处于测试版),它为 Elasticsearch 5.6 到 7.x 提供一流的支持,并且实际上对您的特定问题进行了测试(并且它有效)正确)。然而,Hibernate Search 6 中的 API 有所不同。
关于java - hibernate 搜索中的 ZonedDateTime 的 DateBridge 在索引数据时出现异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59932588/