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



这就是我的实体配置的方式

@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实体被删除,但在图书索引中,我仍然可以看到FrontPage数据。

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

book.setFrontPage(new FrontPage);

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

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

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

我使用的Hibernate版本是,

hibernate搜索弹性搜索,hibernate搜索orm=5.11.4.最终

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

通过将属性hibernate.search.default.elasticsearch.refresh_after_write设置为true,可以在每个索引文档之后请求刷新。如果您这样做,那么在事务提交后,这些更改将立即可见。然而,这会导致性能不佳,所以我不建议在生产中使用它:只需将其用于测试即可。

来自文件:

是否在一组操作完成后执行显式刷新已针对特定索引(真或假(执行

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

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

最新更新