6 Replies Latest reply on May 30, 2012 8:22 PM by sofian22

    Missing KeyTransformer for FileListCacheKey When Using Infinispan as Directory For Lucene

    sofian22

      Hi,

       

      We are using replication clustering mode to cache a simple object whose key is a String type. In order to share the indexes throughout the cluster, we are trying to use infinispan as the directory provider for lucene indexing, using the same DefaultCacheManager that is bound in JNDI.

       

      Artifact info: infinispan-query 5.1.3.FINAL, infinispan-lucene-directory 5.1.3.FINAL, hibernate-search-infinispan 4.1.0.CR1

       

      The cached object is as follows:

       

      {code}

       

      @Indexed

      @Transformable

      @ProvidedId

      public class Contact implements Serializable {

       

          private static final long serialVersionUID = 1L;

       

          @DocumentId

          String uuid;

       

          public String getUuid() {

              return uuid;

          }

       

          public void setUuid(String uuid) {

              this.uuid = uuid;

          }

       

          @Field(index = Index.NO)

          Date created;

       

          public Date getCreated() {

              return created;

          }

       

          public void setCreated(Date created) {

              this.created = created;

          }

       

          @Fields({ @Field(index = Index.YES), @Field(name = "displayName_forSort", analyze = Analyze.NO, store = Store.NO) })

          String displayName;

      }

       

      {code}

       

      However, we keep getting the following error, when we try to putAsync an Object into the cache, even though the cache key is defined as a String (uuid). It seems to be referring to the lucene index data cache, whose key is of FileListCacheKey type, and that it does not have a keyTransformer registered. How do I specify this in the configuration or api?

       

      {code}

       

      Caused by: java.lang.IllegalArgumentException: Indexing only works with entries keyed on Strings, primitives and classes that have the @Transformable annotation - you passed in a class org.infinispan.lucene.FileListCacheKey. Alternatively, see org.infinispan.query.SearchManager#registerKeyTransformer

                at org.infinispan.query.backend.KeyTransformationHandler.keyToString(KeyTransformationHandler.java:164)

                at org.infinispan.query.backend.QueryInterceptor.keyToString(QueryInterceptor.java:290)

                at org.infinispan.query.backend.QueryInterceptor.updateIndexes(QueryInterceptor.java:220)

                at org.infinispan.query.backend.QueryInterceptor.visitPutKeyValueCommand(QueryInterceptor.java:126)

                at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)

                at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:116)

                at org.infinispan.interceptors.locking.OptimisticLockingInterceptor.visitPutKeyValueCommand(OptimisticLockingInterceptor.java:139)

                at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)

                at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:116)

                at org.infinispan.interceptors.base.CommandInterceptor.handleDefault(CommandInterceptor.java:130)

                at org.infinispan.commands.AbstractVisitor.visitPutKeyValueCommand(AbstractVisitor.java:61)

                at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)

                at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:116)

                at org.infinispan.interceptors.TxInterceptor.enlistWriteAndInvokeNext(TxInterceptor.java:211)

                at org.infinispan.interceptors.TxInterceptor.visitPutKeyValueCommand(TxInterceptor.java:149)

                at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)

                at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:116)

                at org.infinispan.interceptors.StateTransferLockInterceptor.handleWithRetries(StateTransferLockInterceptor.java:208)

                at org.infinispan.interceptors.StateTransferLockInterceptor.handleWriteCommand(StateTransferLockInterceptor.java:181)

                at org.infinispan.interceptors.StateTransferLockInterceptor.visitPutKeyValueCommand(StateTransferLockInterceptor.java:152)

                at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)

                at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:116)

                at org.infinispan.interceptors.CacheMgmtInterceptor.visitPutKeyValueCommand(CacheMgmtInterceptor.java:124)

                at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)

                at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:116)

                at org.infinispan.interceptors.base.CommandInterceptor.handleDefault(CommandInterceptor.java:130)

                at org.infinispan.commands.AbstractVisitor.visitPutKeyValueCommand(AbstractVisitor.java:61)

                at org.infinispan.interceptors.IsMarshallableInterceptor.visitPutKeyValueCommand(IsMarshallableInterceptor.java:108)

                at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)

                at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:116)

                at org.infinispan.interceptors.InvocationContextInterceptor.handleAll(InvocationContextInterceptor.java:130)

                at org.infinispan.interceptors.InvocationContextInterceptor.handleDefault(InvocationContextInterceptor.java:89)

                at org.infinispan.commands.AbstractVisitor.visitPutKeyValueCommand(AbstractVisitor.java:61)

                at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)

                at org.infinispan.interceptors.InterceptorChain.invoke(InterceptorChain.java:345)

                at org.infinispan.CacheImpl.executeCommandAndCommitIfNeeded(CacheImpl.java:944)

                at org.infinispan.CacheImpl.putIfAbsent(CacheImpl.java:670)

                at org.infinispan.CacheImpl.putIfAbsent(CacheImpl.java:661)

                at org.infinispan.CacheSupport.putIfAbsent(CacheSupport.java:74)

                at org.infinispan.lucene.FileListOperations.getFileList(FileListOperations.java:65)

                at org.infinispan.lucene.InfinispanDirectory.list(InfinispanDirectory.java:163)

                at org.infinispan.lucene.InfinispanDirectory.listAll(InfinispanDirectory.java:318)

                at org.apache.lucene.index.SegmentInfos$FindSegmentsFile.run(SegmentInfos.java:641)

                at org.apache.lucene.index.SegmentInfos$FindSegmentsFile.run(SegmentInfos.java:593)

                at org.apache.lucene.index.SegmentInfos.read(SegmentInfos.java:359)

                at org.apache.lucene.index.IndexReader.indexExists(IndexReader.java:1076)

                at org.hibernate.search.store.impl.DirectoryProviderHelper.initializeIndexIfNeeded(DirectoryProviderHelper.java:157)

                at org.hibernate.search.infinispan.impl.InfinispanDirectoryProvider.start(InfinispanDirectoryProvider.java:89)

                at org.hibernate.search.indexes.impl.DirectoryBasedIndexManager.initialize(DirectoryBasedIndexManager.java:93)

                at org.hibernate.search.indexes.impl.IndexManagerHolder.createDirectoryManager(IndexManagerHolder.java:241)

                at org.hibernate.search.indexes.impl.IndexManagerHolder.buildEntityIndexBinding(IndexManagerHolder.java:111)

                at org.hibernate.search.spi.SearchFactoryBuilder.initDocumentBuilders(SearchFactoryBuilder.java:411)

                at org.hibernate.search.spi.SearchFactoryBuilder.buildIncrementalSearchFactory(SearchFactoryBuilder.java:168)

                at org.hibernate.search.spi.SearchFactoryBuilder.buildSearchFactory(SearchFactoryBuilder.java:148)

                at org.hibernate.search.impl.MutableSearchFactory.addClasses(MutableSearchFactory.java:193)

                at org.infinispan.query.backend.QueryInterceptor.enableClassesIncrementally(QueryInterceptor.java:256)

                at org.infinispan.query.backend.QueryInterceptor.updateKnownTypesIfNeeded(QueryInterceptor.java:276)

                at org.infinispan.query.backend.QueryInterceptor.visitPutKeyValueCommand(QueryInterceptor.java:122)

                at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)

                at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:116)

                at org.infinispan.interceptors.locking.OptimisticLockingInterceptor.visitPutKeyValueCommand(OptimisticLockingInterceptor.java:139)

                at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)

                at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:116)

                at org.infinispan.interceptors.base.CommandInterceptor.handleDefault(CommandInterceptor.java:130)

                at org.infinispan.commands.AbstractVisitor.visitPutKeyValueCommand(AbstractVisitor.java:61)

                at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)

                at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:116)

                at org.infinispan.interceptors.TxInterceptor.enlistWriteAndInvokeNext(TxInterceptor.java:211)

                at org.infinispan.interceptors.TxInterceptor.visitPutKeyValueCommand(TxInterceptor.java:149)

                at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)

                at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:116)

                at org.infinispan.interceptors.StateTransferLockInterceptor.handleWithRetries(StateTransferLockInterceptor.java:208)

                at org.infinispan.interceptors.StateTransferLockInterceptor.handleWriteCommand(StateTransferLockInterceptor.java:181)

                at org.infinispan.interceptors.StateTransferLockInterceptor.visitPutKeyValueCommand(StateTransferLockInterceptor.java:152)

                at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)

                at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:116)

                at org.infinispan.interceptors.CacheMgmtInterceptor.visitPutKeyValueCommand(CacheMgmtInterceptor.java:124)

                at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)

                at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:116)

                at org.infinispan.interceptors.base.CommandInterceptor.handleDefault(CommandInterceptor.java:130)

                at org.infinispan.commands.AbstractVisitor.visitPutKeyValueCommand(AbstractVisitor.java:61)

                at org.infinispan.interceptors.IsMarshallableInterceptor.visitPutKeyValueCommand(IsMarshallableInterceptor.java:108)

                at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)

                at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:116)

                at org.infinispan.interceptors.InvocationContextInterceptor.handleAll(InvocationContextInterceptor.java:130)

                at org.infinispan.interceptors.InvocationContextInterceptor.handleDefault(InvocationContextInterceptor.java:89)

                at org.infinispan.commands.AbstractVisitor.visitPutKeyValueCommand(AbstractVisitor.java:61)

                at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)

                at org.infinispan.interceptors.InterceptorChain.invoke(InterceptorChain.java:345)

                at org.infinispan.CacheImpl.executeCommandAndCommitIfNeeded(CacheImpl.java:944)

                at org.infinispan.CacheImpl.putAsync(CacheImpl.java:743)

                at org.infinispan.CacheImpl.putAsync(CacheImpl.java:735)

                at org.infinispan.CacheSupport.putAsync(CacheSupport.java:70)

       

      {code}

       

      Here are the snippet of our infinispan xml configuration file:

       

      {code:xml}

       

        <default>

            <indexing enabled="true" indexLocalOnly="false">

               <properties>

       

                   <property name="hibernate.search.default.directory_provider" value="infinispan"/>

                   <property name="hibernate.jndi.class" value="org.jnp.interfaces.NamingContextFactory"/>

                   <property name="hibernate.search.infinispan.cachemanager_jndiname" value ="java:DefaultCacheManager"/>

                   <!-- property name="key2StringMapperClass" value="org.infinispan.lucene.LuceneKey2StringMapper" /-->

       

               </properties>

            </indexing>

       

            <clustering mode="replication">

               <stateRetrieval

                  timeout="20000"

                  fetchInMemoryState="false"

                  alwaysProvideInMemoryState="false"

               />

       

               <async

                  useReplQueue="true"

                  replQueueInterval="1000"

                  replQueueMaxElements="2000"

               />

       

            </clustering>

         </default>

       

      {code}

       

      Can someone review and tell me if I miss anything?

       

       

      I have read an article about the need to specify LuceneKey2StringMapper, but it was referring to JdbcStringBasedCacheStore, and I'm not sure how or where to specify it. I tried putting it as one of the indexing properties, but it does not seem to have any effect.

       

      Any pointer is appreciated. Thanks,

       

      Sofian

        • 1. Re: Missing KeyTransformer for FileListCacheKey When Using Infinispan as Directory For Lucene
          sannegrinovero

          Hi Sofian,

          you should configure separate caches rather than store all in you default cache.

           

          In particular your problem is that you are storing the Lucene index in a cache which is having indexing enabled, that would create a recursion problem.

           

          Use the properties locking_cachename, data_cachename,metadata_cachename
          as defined in http://docs.jboss.org/hibernate/search/4.1/reference/en-US/html_single/#directory-provider-table to specify which caches should be used to store the Lucene Index.

           

          These caches need to be different than the caches you use to store your user objects which are going to be indexed, and it's not required but recommended that you configure three of them; for example the locking cache should not have a CacheLoader defined as there is no good use case for it and it would be costly in terms of efficiency.

           

          So I understood from your stacktrace that you were sharing the caches - which is not recommended - still you should not shave such an error as Infinispan Query should not attempt to index non-indexable types and silently ignore this. That is probably an issue, I've opened https://issues.jboss.org/browse/ISPN-2050 to at least improve the error message.

          • 2. Re: Missing KeyTransformer for FileListCacheKey When Using Infinispan as Directory For Lucene
            sofian22

            I've added the following the config file:

             

               <default>

                  <indexing enabled="true" indexLocalOnly="false">

                     <properties>

                        <property name="hibernate.search.lucene_version" value="LUCENE_35" />

                        <property name="hibernate.search.default.directory_provider" value="infinispan"/>

                        <property name="hibernate.jndi.class" value="org.jnp.interfaces.NamingContextFactory"/>

                        <property name="hibernate.search.infinispan.cachemanager_jndiname" value ="java:DefaultCacheManager"/>

                        <property name="hibernate.search.infinispan.locking_cachename" value ="LuceneIndexesLocking"/>

                        <property name="hibernate.search.infinispan.data_cachename" value ="LuceneIndexesData"/>

                        <property name="hibernate.search.infinispan.metadata_cachename" value ="LuceneIndexesMetadata"/>

                     </properties>

                  .....

               </default>

             

               <namedCache name="LuceneIndexesLocking">

                  <indexing enabled="false" />

                  <clustering mode="replication">

                     <async

                        useReplQueue="true"

                     />

                  </clustering>

               </namedCache>

               <namedCache name="LuceneIndexesData">

                  <indexing enabled="false" />

                  <clustering mode="replication">

                     <async

                        useReplQueue="true"

                     />

                  </clustering>

               </namedCache>

               <namedCache name="LuceneIndexesMetadata">

                  <indexing enabled="false" />

                  <clustering mode="replication">

                     <async

                        useReplQueue="true"

                     />

                  </clustering>

               </namedCache>

             

            The debug trace seems to indicate that these caches are started, but I'm still getting the same error:

             

            2012-05-17 12:05:24,615 DEBUG [CacheViewsManagerImpl] (CacheViewInstaller-2,BoxeyCacheCluster-18040) Successfully installed view CacheView{viewId=1, members=[BoxeyCacheCluster-18040]} for cache LuceneIndexesMetadata

            2012-05-17 12:05:24,615 DEBUG [CacheImpl] (CacheStartThread,infinispan-cluster,LuceneIndexesMetadata) Started cache LuceneIndexesMetadata on BoxeyCacheCluster-18040

            2012-05-17 12:05:24,644 DEBUG [CacheViewsManagerImpl] (CacheViewInstaller-2,BoxeyCacheCluster-18040) Successfully installed view CacheView{viewId=1, members=[BoxeyCacheCluster-18040]} for cache LuceneIndexesData

            2012-05-17 12:05:24,644 DEBUG [CacheImpl] (CacheStartThread,infinispan-cluster,LuceneIndexesData) Started cache LuceneIndexesData on BoxeyCacheCluster-18040

            2012-05-17 12:05:24,648 DEBUG [CacheViewsManagerImpl] (CacheViewInstaller-2,BoxeyCacheCluster-18040) Successfully installed view CacheView{viewId=1, members=[BoxeyCacheCluster-18040]} for cache LuceneIndexesLocking

            2012-05-17 12:05:24,648 DEBUG [CacheImpl] (CacheStartThread,infinispan-cluster,LuceneIndexesLocking) Started cache LuceneIndexesLocking on BoxeyCacheCluster-18040

            2012-05-17 12:05:24,742 ERROR [InvocationContextInterceptor] (RMI TCP Connection(2)-10.154.136.172) ISPN000136: Execution error

            java.lang.IllegalArgumentException: Indexing only works with entries keyed on Strings, primitives and classes that have the @Transformable annotation - you passed in a class org.infinispan.lucene.FileListCacheKey. Alternatively, see org.infinispan.query.SearchManager#registerKeyTransformer

                      at org.infinispan.query.backend.KeyTransformationHandler.keyToString(KeyTransformationHandler.java:164)

                      at org.infinispan.query.backend.QueryInterceptor.keyToString(QueryInterceptor.java:290)

                      at org.infinispan.query.backend.QueryInterceptor.updateIndexes(QueryInterceptor.java:220)

                      at org.infinispan.query.backend.QueryInterceptor.visitPutKeyValueCommand(QueryInterceptor.java:126)

             

             

            I did not specify a CacheLoader for the locking cache.

             

            Could you please review the config file that we have?

             

            Thanks,

            Sofian

            • 3. Re: Missing KeyTransformer for FileListCacheKey When Using Infinispan as Directory For Lucene
              sannegrinovero

              Hi Sofian,

              it looks like you still have the indexing engine triggering; the instance having class org.infinispan.lucene.FileListCacheKey is one of the keys used to store the index itself in the cache.

               

              Your configuration looks like correct as it's storing the index segments in the three caches having indexing disabled, still that's not happening. I verified that we do have a test verifying indexing is disabled correctly if you specify indexing enabled=false to override the setting from the default cache, but this unit test is limited to the configuration parser.. from your logs it looks like the configuration is not applied correctly in some of the internals.

               

              Could you please try two things:

              1) Remove the indexing options from the default cache: use a different cache, so that the others won' t inherit from it (even if this should work - apparently it's not)

              2) Open a JIRA issue, this is a problem that needs to be solved: https://issues.jboss.org/browse/ISPN

              3) If you can, add a test to the JIRA issue?

               

              thanks for reporting this!

              • 4. Re: Missing KeyTransformer for FileListCacheKey When Using Infinispan as Directory For Lucene
                sofian22

                Hi Sanne,

                 

                I've modified the code and config file to use a different cache (instead of using default cache) for storing the Contact objects, and moved the <indexing> from default cache to this new pbCache, as such:

                 

                   <namedCache name="pbCache">

                      <indexing enabled="true" indexLocalOnly="true">

                         <properties>

                            <property name="hibernate.search.lucene_version" value="LUCENE_35" />

                            <property name="hibernate.search.default.directory_provider" value="infinispan"/>

                            <property name="hibernate.jndi.class" value="org.jnp.interfaces.NamingContextFactory"/>

                            <property name="hibernate.search.infinispan.cachemanager_jndiname" value ="java:DefaultCacheManager"/>

                            <property name="hibernate.search.infinispan.locking_cachename" value ="LuceneIndexesLocking"/>

                            <property name="hibernate.search.infinispan.data_cachename" value ="LuceneIndexesData"/>

                            <property name="hibernate.search.infinispan.metadata_cachename" value ="LuceneIndexesMetadata"/>

                         </properties>

                      </indexing>

                      <clustering mode="replication">

                         <stateRetrieval fetchInMemoryState="true"

                            alwaysProvideInMemoryState="true"/>

                         <async

                            useReplQueue="true"

                            replQueueInterval="1000"

                            replQueueMaxElements="2000"

                         />

                      </clustering>

                   </namedCache>

                 

                With this config, the same use case no longer shows the FileListCacheKey error any longer. Putting a contact C1 in node N1 would now replicate it to node N2, and a lucene query in either N1 or N2 would perfectly return C1, which implies index is correctly updated in both nodes.  However, when I try to do another async put of contact C2 in node N2, it fails to update the index in that node N2 with LockObtainFailedException, as shown below. The C2 object is created just fine in the cache.

                 

                208023 [RMI TCP Connection(2)-10.154.137.47] INFO com.sn.cache.InfinispanCacheListener - Event cache created  :EventImpl{pre=false, key=f82540e3-ba57-4147-ab34-d2fb8319a991, transaction=GlobalTransaction:<BoxeyCacheCluster-48328>:5:local, originLocal=true, transactionSuccessful=false, type=CACHE_ENTRY_CREATED, value=null}

                2012-05-22 13:45:53,328 DEBUG [LocalQueryInterceptor] (RMI TCP Connection(2)-10.154.137.47) Entry is changed

                2012-05-22 13:45:54,335 ERROR [LogErrorHandler] (Hibernate Search: Index updates queue processor for index com.sn.cache.model.Contact-1) HSEARCH000058: Exception occurred org.apache.lucene.store.LockObtainFailedException: Lock obtain timed out: org.infinispan.lucene.locking.BaseLuceneLock@324ff

                Primary Failure:

                          Entity com.sn.cache.model.Contact  Id S:f82540e3-ba57-4147-ab34-d2fb8319a991  Work Type  org.hibernate.search.backend.UpdateLuceneWork

                 

                org.apache.lucene.store.LockObtainFailedException: Lock obtain timed out: org.infinispan.lucene.locking.BaseLuceneLock@324ff

                          at org.apache.lucene.store.Lock.obtain(Lock.java:84)

                          at org.apache.lucene.index.IndexWriter.<init>(IndexWriter.java:1108)

                          at org.hibernate.search.backend.impl.lucene.IndexWriterHolder.createNewIndexWriter(IndexWriterHolder.java:127)

                          at org.hibernate.search.backend.impl.lucene.IndexWriterHolder.getIndexWriter(IndexWriterHolder.java:102)

                          at org.hibernate.search.backend.impl.lucene.AbstractWorkspaceImpl.getIndexWriter(AbstractWorkspaceImpl.java:119)

                          at org.hibernate.search.backend.impl.lucene.LuceneBackendQueueTask.applyUpdates(LuceneBackendQueueTask.java:99)

                          at org.hibernate.search.backend.impl.lucene.LuceneBackendQueueTask.run(LuceneBackendQueueTask.java:67)

                          at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)

                          at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)

                          at java.util.concurrent.FutureTask.run(FutureTask.java:138)

                          at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)

                          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)

                          at java.lang.Thread.run(Thread.java:662)

                2012-05-22 13:45:54,335 ERROR [LuceneBackendQueueTask] (Hibernate Search: Index updates queue processor for index com.sn.cache.model.Contact-1) HSEARCH000072: Couldn't open the IndexWriter because of previous error: operation skipped, index ouf of sync!

                 

                What could've caused the lock to not be obtainable in node N2?

                 

                Thanks,

                Sofian

                • 5. Re: Missing KeyTransformer for FileListCacheKey When Using Infinispan as Directory For Lucene
                  sannegrinovero

                  Hi Sofian,

                  regarding your initial problem, we had tests covering the configuratin parsing, I've now added

                  https://github.com/Sanne/infinispan/blob/e90cc9c7d2f1a810da0cbe73ac2228ab4fd27ef6/query/src/test/java/org/infinispan/query/config/DefaultCacheInheritancePreventedTest.java

                   

                  (you can see it in context from https://github.com/Sanne/infinispan/commit/e90cc9c7d2f1a810da0cbe73ac2228ab4fd27ef6 )

                  Do you think you could adapt it in some way to be able to reproduce the problem you had?

                   

                  Onwards on your second problem:

                  Hibernate Search acquires an eager lock on the index for writing, and keeps it until it's shut down as that gets you better performance on writing. You can disable this by setting the propery

                   

                  hibernate.search.default.exclusive_index_use = false

                   

                  That's the simple way, but not what I would suggest as you might get in lock acquire timeouts if you are frequently writing from multiple nodes.

                  The better solution is to configure a single node as a master indexer, and configure the other nodes as slaves to have all index update operations performed by the master; please see this chapter in the Hibernate Search reference: http://docs.jboss.org/hibernate/search/4.1/reference/en-US/html_single/#d0e652

                   

                  We're working on making this configuration simple, especially I'm not liking the notion of a "master" node; if you want you could try out some new experimental things, but the JMS approach described there is the only one which I would suggest someone needing a quick rollout in production.

                  • 6. Re: Missing KeyTransformer for FileListCacheKey When Using Infinispan as Directory For Lucene
                    sofian22

                    Hi Sanne,

                     

                    Thanks, that was it. Setting the exclusive_index_use to false did fix the LockObtainFailedException, so now I have both the objects and indexes replicated nicely to all the nodes.

                     

                    I have not yet tried the hibernate search config with master indexer as you suggested. For now, I make the apps to always call Cache.putAsync() method from the same node. With this, I discover a new problem where the app in node N1 puts hundreds of objects, followed immediately by running multiple concurrent queries in node N1 and subsequently in node N2. The queries in N1 came back fine, but the queries in N2 will get stuck indefinitely in the CacheQueryImpl.list().  If I add a one second sleep between the put and the queries, then the problem will not manifest. It looks like some kind of race condition between the index replication and query execution in N2, where query would get stuck if it happens while index is being replicated from N1 to N2.

                     

                    Is this expected?

                     

                    The querying code is fairly simple, as follows:

                     

                    {code}

                     

                            SearchManager searchManager = org.infinispan.query.Search.getSearchManager(cache);

                            QueryBuilder queryBuilder = searchManager.buildQueryBuilderForClass(Contact.class).get();

                     

                            org.apache.lucene.search.Query luceneQuery = null;

                            displayName = displayName.replace("-", " ").trim();

                            displayName = displayName.toLowerCase();

                            displayName += "*";

                            luceneQuery = queryBuilder.keyword().wildcard().onField("displayName").matching(displayName).createQuery();

                     

                            CacheQuery query = searchManager.getQuery(luceneQuery, Contact.class);

                            org.apache.lucene.search.Sort sort = new Sort(new SortField("displayName_forSort", SortField.STRING));

                            if (maxResult > 0) {

                                query.maxResults(maxResult);

                            }

                            query.sort(sort);

                     

                            List objectList = query.list();

                     

                    {code}

                     

                    I first tried to use a basic non-shared ram-based index directory provider, but I could not even get that to work (https://community.jboss.org/message/736543#736543). I must miss something really fundamental there, but it is not obvious to me.