Hibernate搜索Lucene:通过删除子实体来更新索引文档,使子实体在索引文档中成为孤立的

时间:2020-02-20 10:38:51

标签: java hibernate elasticsearch lucene hibernate-search

这是配置我的实体的方式

@Entity
@Indexed
public class Book{

    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "book")
    @IndexedEmbedded
    private FrontPage frontPage;

...//other data
}
@Entity
public class FrontPage{

    @OneToOne(cascade = {}, fetch = FetchType.EAGER, targetEntity = Book.class)
    @JoinColumn(name = "book_id", nullable = false)
    @ContainedIn
    private Book book;

...//other data

}

这就是我的集成测试的样子

@Test
public void testMerge_RemoveFrontPage() {
    insertDataSet("dataset.xml");

    Book book = getEntityManager().find(Book.class, 2000L);
    //this book instance already have data

    book.setFrontPage(null);

    dao.merge(book);

    //verify after commit
    //In database the FrontPage entity reference is removed

}

通过查看数据库,FrontPage实体被删除,但是在Book索引中,我仍然可以看到FrontPage数据。

如果我尝试替换这样的FrontPage数据,并且现在在Book索引中可以看到两个FrontPage数据,也会发生同样的事情。

book.setFrontPage(new FrontPage);

通过调试,FullTextIndexEventListener在日志中记录以下警告,不确定是否合理,但我怀疑这可能是原因。

org.hibernate.search.event.impl.FullTextIndexEventListener:250-HSEARCH000024:在集合更改时无法为实体重新编制索引,无法提取ID:com.x.x.x.FrontPage

不确定这里出了什么问题或预期的行为?

我使用的休眠版本是

hibernate-search-elasticsearch,hibernate-search-orm = 5.11.4.Final

1 个答案:

答案 0 :(得分:0)

默认情况下,Elasticsearch后端的索引编制接近实时,这意味着更改需要一些时间才能在搜索查询中可见。默认情况下,只需要一秒钟。

通过将属性hibernate.search.default.elasticsearch.refresh_after_write设置为true,可以在每个索引文档之后请求刷新。如果执行此操作,则在事务提交后该更改将立即可见。但是,这会导致性能下降,因此我不建议在生产环境中使用它,只需将其用于测试即可。

来自documentation

在执行一组操作后是否执行显式刷新 已针对特定索引(正确或错误)执行

hibernate.search.default.elasticsearch.refresh_after_write false (default)

这在单元测试中很有用,以确保查询可以立即看到写入而不会延迟。这使单元测试更加简单。您 不应依赖于生产代码的同步行为 除非在极少数情况下,否则Elasticsearch已针对异步进行了优化 写道:保留false以获得最佳性能。