这就是我的实体配置的方式
@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以获得最佳性能。