Hi all,
I'm facing a strange issue and I hope some of you may help me.
When I try to use MassIndexer, I've got the following exception:
Code:
15:49:23,653 ERROR [org.hibernate.search.exception.impl.LogErrorHandler] (Hibernate Search: collectionsloader-1) HSEARCH000058: HSEARCH000116: Unexpected error during MassIndexer operation: org.hibernate.HibernateException: illegally attempted to associate a proxy with two open Sessions
at org.hibernate.proxy.AbstractLazyInitializer.setSession(AbstractLazyInitializer.java:112) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
at org.hibernate.engine.internal.StatefulPersistenceContext.reassociateProxy(StatefulPersistenceContext.java:606) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
at org.hibernate.engine.internal.StatefulPersistenceContext.reassociateIfUninitializedProxy(StatefulPersistenceContext.java:565) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
at org.hibernate.event.internal.ProxyVisitor.processEntity(ProxyVisitor.java:49) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:124) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:82) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
at org.hibernate.event.internal.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:76) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
at org.hibernate.event.internal.AbstractVisitor.process(AbstractVisitor.java:143) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
at org.hibernate.event.internal.AbstractReassociateEventListener.reassociate(AbstractReassociateEventListener.java:98) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
at org.hibernate.event.internal.DefaultLockEventListener.onLock(DefaultLockEventListener.java:81) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
at org.hibernate.internal.SessionImpl.fireLock(SessionImpl.java:724) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
at org.hibernate.internal.SessionImpl.fireLock(SessionImpl.java:717) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
at org.hibernate.internal.SessionImpl.access$1700(SessionImpl.java:170) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
at org.hibernate.internal.SessionImpl$LockRequestImpl.lock(SessionImpl.java:2276) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
at org.hibernate.search.batchindexing.impl.EntityConsumerLuceneWorkProducer.indexAllQueue(EntityConsumerLuceneWorkProducer.java:131) [hibernate-search-orm-4.1.0.Final.jar:4.1.0.Final]
at org.hibernate.search.batchindexing.impl.EntityConsumerLuceneWorkProducer.run(EntityConsumerLuceneWorkProducer.java:102) [hibernate-search-orm-4.1.0.Final.jar:4.1.0.Final]
at org.hibernate.search.batchindexing.impl.OptionallyWrapInJTATransaction.run(OptionallyWrapInJTATransaction.java:112) [hibernate-search-orm-4.1.0.Final.jar:4.1.0.Final]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [rt.jar:1.7.0_01]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [rt.jar:1.7.0_01]
at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_01]
This issue occurs even when I use @Indexed on only one entity! This entity has many fields but only one field annotated with @Field :
Code:
@Entity
@Table(name = "DIR_UNITE_FONCTIONNELLE_UFC")
@DiscriminatorValue("UFC")
@ForeignKey(name = "FK_UFC_STR")
@Indexed
public class UniteFonctionnelle extends Structure implements Serializable {
@Column(name = "UFC_ID_LOCAL", nullable = false)
@NotBlank(message="{uf.required.local_id}")
@Field(store=Store.YES, analyze=Analyze.NO)
private String idLocal;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "UFC_ENTITE_JURIDIQUE", referencedColumnName = "STR_ID", nullable = false)
@ForeignKey(name = "FK_UFC_EJR")
private EntiteJuridique entiteJuridique;
... and more fields ...
My classes have the following hierarchy:
UniteFonctionnelle -- inherit from --> Structure
EntiteJuridique -- inherit from --> Structure
Structure, UniteFonctionnelle and EntiteJuridique are stored in differents tables. EntiteJuridique does not have (currently) the @Indexed annotation (nor Structure). Structure class own the @Id field.
Note: this issue appears even if I set luceneWorkerBuildingThreadNum to 1 and luceneWorkerBuildingThreadNum = 1.
I looked into the code (hibernate-search 4.1.0 final and hibernate-core 4.1.0 final) and here is my analysis:
- in BatchIndexingWorkspace.run method, 1 instance of EntityConsumerLuceneWorkProducer, 1 instance of IdentifierConsumerEntityProducer and 1 instance of IdentifierProducer are created (according to luceneWorkerBuildingThreadNum and luceneWorkerBuildingThreadNum).
- first IdentifierProducer is run and requests the DB to retrieve IDs
- then IdendifierConsumerEntityProducer is run and hits the DB to retrieve entities but as the field entiteJuridique is LAZY then hibernate creates a proxy (and this proxy is associated with the current session)
- at last EntityConsumerLuceneWorkProducer is run (consumes entities produced by IdendifierConsumerEntityProducer). First I don't know why but this producer tries to load the field entiteJuridique even if this attribut is not part of the document! As it wants to load the proxy it tries to associate a session to the proxy (which has already one session) => Exception
These producers / consumers are wrapped by an OptionallyWrapInJTATransaction, which creates a new session when there's no JTA transaction (my case). So each producer/consumer has a different session.
[edit] I made a mistake OptionallyWrapInJTATransaction does not create a new session when there's no JTA transaction: it calls run with null parameter. But as there's no upper session, the wrapped instance use
Code:
sessionFactory.openSession()
to get a new session.
I think that this use case is quite common, so may be I have something wrong with my configuration?
Any help would be very, very appreciate.
Thank you so much.
Eric