1

我们最近升级到 Hibernate Search 4.1,当我们基于 hibernate 对锁所做的更改运行 JUnit 测试时遇到错误。当我们使用AbstractTransactionalJUnit4SpringContextTests运行 Junit 测试时,我们经常会看到每次测试后都会留下锁。在审查(如何处理 Hibernate-Search 索引恢复)时,我们尝试了本机锁,但这并没有解决问题。

我们已经使用默认目录提供程序 (Filestore) 尝试了各种锁定机制(简单、单一和本机),并经常看到如下消息:

build   20-Apr-2012 07:07:53    ERROR 2012-04-20 07:07:53,290 154053 (LogErrorHandler.java:83) org.hibernate.search.exception.impl.LogErrorHandler  - HSEARCH000058: HSEARCH000117: IOException on the IndexWriter
build   20-Apr-2012 07:07:53    org.apache.lucene.store.LockObtainFailedException: Lock obtain timed out: NativeFSLock@target/indexes/Resource/write.lock
build   20-Apr-2012 07:07:53        at org.apache.lucene.store.Lock.obtain(Lock.java:84)
build   20-Apr-2012 07:07:53        at org.apache.lucene.index.IndexWriter.<init>(IndexWriter.java:1108)

或者

build   19-Apr-2012 19:31:09    ERROR 2012-04-19 19:31:09,395 153552 (LuceneBackendTaskStreamer.java:61) org.hibernate.search.backend.impl.lucene.LuceneBackendTaskStreamer  - HSEARCH000072: Couldn't open the IndexWriter because of previous error: operation skipped, index ouf of sync!

其中一些消息似乎显示了从一个测试级联到另一个测试的锁定问题,因此需要重置,有些可能是有效的,因为测试正在测试“无效”行为以及我们的应用程序如何对它们做出反应,但通常是因为ID 为 null 的情况

build   19-Apr-2012 19:31:11    Primary Failure:
build   19-Apr-2012 19:31:11        Entity org.tdar.core.bean.resource.CodingSheet  Id null  Work Type  org.hibernate.search.backend.PurgeAllLuceneWork

但是,无论如何,我们需要确保一项测试不会影响另一项测试。

在阅读一些讨论(关于目录提供程序的电子邮件讨论)时,有人建议基于 RAM 的目录提供程序可能是一个更好的选择,但我们更愿意尽可能使用与生产环境相同的提供程序。

我们应该如何在测试之间重置 HibernateSearch 以清理锁定文件并重置索引不同步或损坏的潜在问题?在测试套件开始时,我们擦除索引目录,是否建议在每次测试后擦除它?

谢谢

4

2 回答 2

2

如果您在目录中有过时的锁,则意味着 Hibernate Search 没有正确关闭,因为它肯定会关闭锁。

如果你在每个测试中启动一个新的 Hibernate SessionFactory,你应该确保它在测试运行后也被关闭:

org.hibernate.SessionFactory.close()

(这在许多示例中经常丢失,因为忘记关闭 Hibernate SessionFactory 时没有明显的问题,但从来都不是可选的,并且可能会泄漏连接或线程)。

您链接到的 Hibernate 邮件列表中的线程最终将锁定更改为使用 Hibernate Search 4.1 中的本机句柄,以便在 JVM 崩溃或被杀死时自动清除锁定。但在你的情况下,我猜你并没有在测试之间杀死虚拟机,所以你只需要通过关闭服务来确保锁被正确释放。

exclusive_index_use=false隐藏了问题,因为 IndexWriter 将在每个事务结束时关闭。但是,这使它变慢了,因为重用 IndexWriter 的效率要高得多。升级到 Hibernate Search 4.1 后出现此问题的原因是此选项默认更改为true。但即便如此,您仍然应该正确关闭它。

于 2012-04-25T19:47:40.820 回答
0

我的理解是 Spring 管理 SessionFactory 生命周期,所以没有必要随时调用 close()。

在测试运行期间加载了多个上下文时,我看到了这个锁定错误。例如,第一个上下文在索引文件上创建锁。第二个上下文尝试访问相同的索引,但由于第一个上下文中存在打开的 SessionFactory 而失败。

我已经通过使用@DirtiesContext 解决了这个问题,它在下一个实例化之前关闭上下文

于 2013-11-06T20:54:37.980 回答