java - hibernate 搜索中的 ZonedDateTime 的 DateBridge 在索引数据时出现异常

标签 java hibernate elasticsearch lucene hibernate-search

我的实体有一个 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]

最佳答案

ZoneOffsetZoneId,因此此代码是正确的:

    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/

相关文章:

java - 将泛型类型求和为 double

java - 不是 JAX-WS 中的有效服务异常

java - 通过java从mysql的数据创建json对象

java - 与 hibernate 注解的接口(interface)

java - 根据软件许可证标志更改 JAAS 角色

json - 如何使用 set_fact 打印数组变量以在 ansible add_host 模块中使用

java - 如何在java中让android手机静音

java - Spring 中使用 HibernateTemplate 的 ModelMapper 的奇怪行为

java - 使用@Query 在 ElasticSearch 中设置大小

elasticsearch - AWS ElasticSearch服务-我可以在其上使用任何茎干吗?