首页 > 解决方案 > 未加载实体集合时索引失败并使用 LazyInitializationException 中断事务

问题描述

我在我的 UI 中加载了一个实体,更改了一些内容并使用新事务更新了我的实体,但是 Hibernate Search 在我的事务中拦截并尝试更新搜索索引。那会找到,除非它尝试加载一个@IndexedEmbedded()未使用的带有注释的集合,因此会抛出一个LazyInitializationException.

我怎样才能防止这种情况?

Caused by: org.hibernate.HibernateException: Error while indexing in Hibernate Search (before transaction completion) 
    at org.hibernate.search.event.impl.EventSourceTransactionContext$DelegateToSynchronizationOnBeforeTx.doBeforeTransactionCompletion(EventSourceTransactionContext.java:173) 
    at org.hibernate.engine.spi.ActionQueue$BeforeTransactionCompletionProcessQueue.beforeTransactionCompletion(ActionQueue.java:954) 
    at org.hibernate.engine.spi.ActionQueue.beforeTransactionCompletion(ActionQueue.java:525) 
    at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2480) 
    at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:473) 
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:178) 
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:39) 
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:271)
    at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:98) 
        ... 76 common frames omitted 
Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: de.foo.Bar, could not initialize proxy - no Session
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:597) 
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:216) 
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:576) 
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:147) 
    at org.hibernate.collection.internal.PersistentSet.iterator(PersistentSet.java:188) 
    at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.buildDocumentFieldsForEmbeddedObjects(DocumentBuilderIndexedEntity.java:553) 
    at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.buildDocumentFields(DocumentBuilderIndexedEntity.java:482) 
    at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.buildDocumentFieldsForEmbeddedObjects(DocumentBuilderIndexedEntity.java:593) 
    at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.buildDocumentFields(DocumentBuilderIndexedEntity.java:482) 
    at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.getDocument(DocumentBuilderIndexedEntity.java:402) 
    at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.createAddWork(DocumentBuilderIndexedEntity.java:299) 
    at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.addWorkToQueue(DocumentBuilderIndexedEntity.java:241) 
    at org.hibernate.search.engine.impl.WorkPlan$PerEntityWork.enqueueLuceneWork(WorkPlan.java:560) 
    at org.hibernate.search.engine.impl.WorkPlan$PerClassWork.enqueueLuceneWork(WorkPlan.java:322) 
    at org.hibernate.search.engine.impl.WorkPlan.getPlannedLuceneWork(WorkPlan.java:188) 
    at org.hibernate.search.backend.impl.WorkQueue.prepareWorkPlan(WorkQueue.java:115) 
    at org.hibernate.search.backend.impl.BatchedQueueingProcessor.prepareWorks(BatchedQueueingProcessor.java:55) 
    at org.hibernate.search.backend.impl.PostTransactionWorkQueueSynchronization.beforeCompletion(PostTransactionWorkQueueSynchronization.java:67) 
    at org.hibernate.search.event.impl.EventSourceTransactionContext$DelegateToSynchronizationOnBeforeTx.doBeforeTransactionCompletion(EventSourceTransactionContext.java:170) 
        ... 84 common frames omitted

标签: hibernatehibernate-search

解决方案


发生这种情况时,通常意味着您关闭了用于加载实体的会话,并尝试使用另一个会话更新实体。它发生在某些框架中,由于某种原因,您需要在加载和实际更新之间序列化实体。

最简单的解决方案是:不要在不同的会话中分离和使用实体,它只会让你头疼。而且我说的不仅仅是休眠搜索。

如果您真的想这样做,这是可能的,但并不像最初看起来那么明显。

至少有一些方法可以避免在 Wicket 中使用分离的实体。对于其他框架,在不了解您的 UI 框架的情况下,我真的无能为力。如果它是我不知道的 UI 框架,我怀疑我能提供帮助,但值得一试;)

如果您决定提供更多信息,请至少提及:您正在使用的 Hibernate ORM 和 Hibernate Search 版本,以及您在与 Session/EntityManager ( .persist(), .merge(), .saveOrUpdate(), ...) 和 UI交互时使用的确切代码与在组件之间存储/传输实体相关的代码。


推荐阅读