Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate搜索分页奇怪的行为_Hibernate_<img Src="//i.stack.imgur.com/RUiNP.png" Height="16" Width="18" Alt="" Class="sponsor Tag Img">elasticsearch_Hibernate Search - Fatal编程技术网 elasticsearch,hibernate-search,Hibernate,elasticsearch,Hibernate Search" /> elasticsearch,hibernate-search,Hibernate,elasticsearch,Hibernate Search" />

Hibernate搜索分页奇怪的行为

Hibernate搜索分页奇怪的行为,hibernate,elasticsearch,hibernate-search,Hibernate,elasticsearch,Hibernate Search,嗨,我们正在使用hibernate搜索和elasticsearch 索引工作如预期,但是我们在分页结果时看到奇怪的行为 org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery(query, Person.class).setFirstResult(0).setMaxResults(10); return hibQuery.list(); 如果省略setFirstResult(0).setM

嗨,我们正在使用hibernate搜索和elasticsearch

索引工作如预期,但是我们在分页结果时看到奇怪的行为

org.hibernate.Query hibQuery =
            fullTextSession.createFullTextQuery(query, 
Person.class).setFirstResult(0).setMaxResults(10);

return hibQuery.list();
如果省略setFirstResult(0).setMaxResults(10),我们将得到700个结果,但设置了两个参数后,我们将得到0个结果

进一步的研究表明,问题在于hibernate搜索中QueryLoader中的这段代码

objectInitializer.initializeObjects(
            entityInfos,
            idToObjectMap,
            new ObjectInitializationContext( criteria, entityType, extendedIntegrator, timeoutManager, session )
    );

ArrayList<Object> result = new ArrayList<>( idToObjectMap.size() );
    for ( Object o : idToObjectMap.values() ) {
        if ( o != ObjectInitializer.ENTITY_NOT_YET_INITIALIZED ) {
            result.add( o );
        }
    }
    return result;
对于所有idToObjectMap条目返回false

进一步的研究表明,hibernate构建了查询,sql看起来是正确的,但是在QueryParanters中,object callable被设置为false,并且查询永远不会执行

相关LIB

compile "org.hibernate:hibernate-core:5.9.2.Final"
compile "org.hibernate:hibernate-search-orm:5.9.2.Final"
compile "org.hibernate:hibernate-search-elasticsearch:5.9.2.Final"

如果您能帮助解释为什么会发生这种情况,以及如何正确实现分页,我们将不胜感激。

当实体出现在索引中时,通常会出现这种情况,但数据库中不再出现这种情况。在您的例子中,前10个结果似乎在索引中,但不在数据库中

这种行为的原因是Elasticsearch是“接近实时的”:在我们对索引进行更改后,更改将需要一段时间(通常几秒钟)才能在搜索结果中显示出来。因此,如果您只是在几毫秒之前删除了实体,索引状态可能会“滞后”于数据库状态

如果确定数据库中仍然存在实体,则ID映射或选择的特定查询配置可能存在问题。如果未使用默认值,请向我们显示
Person
类的代码,并提供您为属性
hibernate.search.query.object\u lookup\u方法
hibernate.search.query.database\u retrieval\u方法
设置的值

试验中的溶液 如果测试时出现问题,可以将
hibernate.search.default.elasticsearch.refresh\u-after\u-write
设置为
true
但不应在生产中设置此项,因为这将大大降低索引的性能

生产中的溶液 如果这是生产中的一个问题,并且您需要有效地解决它,那么它将更加困难。我能想到的唯一解决方案是从按索引分页改为按键分页。但是,您将失去直接转到页面的功能,并且无法按任何方式对结果进行排序

您需要在结果中找到一个严格单调的键,即保证每个结果唯一的字段,并且在转到下一个结果时总是增加(或总是减少)。如果您按id排序,id将是一个很好的候选者。如果创建日期足够精确,并且您按此创建日期排序,那么创建日期也可以工作

您将使用此键忽略前面的页面:客户端不会将页码发送到服务器,它将发送“严格单调”键的最后一个值,您只需向查询中添加一个类似这样的谓词:
queryBuilder.range().onField(“myKey”).over().createQuery()

然后,不直接返回查询结果,而是多次执行查询,将结果累积到列表中,直到达到适当的页面大小(或直到
getResultSize
返回0)

编辑:另一种解决方案,可能更简单,但这只会降低出现此问题的可能性,而不会完全消除它

通过将所有索引设置为比默认值更短的值(
1s
),可以确保Elasticsearch更频繁地刷新其索引。注意,这可能会对Elasticsearch集群的性能产生非常坏的影响,具体取决于您写入集群的频率


要将该设置应用于所有索引,最简单的解决方案是在Hibernate Search创建索引之前创建。

您好,谢谢您的评论。对象存在于数据库中,我们使用所有默认设置。我发现了正在发生的事情,但不知道为什么。我将把这些信息添加到我的原始问题中。嗨,我发现这些对象已经不在数据库中了。我们不会删除应用程序中的对象,因此我假设它们就在那里。但是,我们在dev中有一个单独的作业,用于清理数据库,我必须在创建索引后运行它。问题是,外部作业实际上使用原始sql从数据库中删除了一些条目,这导致了问题。再次感谢@yrodiere为我指明了正确的方向,也感谢其他有用的提示。
compile "org.hibernate:hibernate-core:5.9.2.Final"
compile "org.hibernate:hibernate-search-orm:5.9.2.Final"
compile "org.hibernate:hibernate-search-elasticsearch:5.9.2.Final"