Ошибка «Транзакция не запущена в текущем потоке»

#java #lucene #xodus

#java #lucene #xodus

Вопрос:

У меня есть этот код, который должен индексировать документ:

   @Override public Boolean index(String dir, String entityId, Double longitude, Double latitude)
      throws Exception {
    if (writer == null) {
      writer = DatabaseManagerImpl.getInstance().getIndexWriter(dir);
    }
    Document doc = new Document();
    doc.add(new StoredField("entityId", entityId));
    doc.add(new LatLonPoint("latlon", latitude, longitude));
    Geo3DPoint point = new Geo3DPoint("geo3d", latitude, longitude);
    doc.add(point);
    writer.addDocument(doc);
    return null;
  }
 

С этой конфигурацией записи индекса:

   public IndexWriter getIndexWriter(String dir) {
    ContextualEnvironment env = Environments.newContextualInstance(dir);
    ExodusDirectory exodusDirectory = new ExodusDirectory(env, VfsConfig.DEFAULT, StoreConfig.WITHOUT_DUPLICATES_WITH_PREFIXING, new ExodusDirectoryConfig());
    Analyzer analyzer = new StandardAnalyzer();
    IndexWriterConfig iwc = new IndexWriterConfig(analyzer);
    iwc.setOpenMode(IndexWriterConfig.OpenMode.CREATE);
    IndexWriter writer = env.computeInTransaction(txn -> {
      try {
        return new IndexWriter(exodusDirectory, iwc);
      } catch (IOException e) {
        return null;
      }
    });
    return writer;
  }
 

И используется как таковой:

   public void testSearch() throws Exception {
    String environment = TestEnvironment.getEnvironment();
    LuceneIndexer luceneIndexer = LuceneIndexerImpl.getInstance();
    luceneIndexer.index(environment, "0-1", lon, lat);
    List<String> results = luceneIndexer.searchNeighbor(environment, lon, lat,
        10.0, null, 10);
    Assert.assertTrue(results.contains("0-1"));
  }
 

Он выдает:

java.lang.Исключение IllegalStateException: транзакция не запущена в текущем потоке

в jetbrains.exodus.env.ContextualEnvironmentImpl.getAndCheckCurrentTransaction(ContextualEnvironmentImpl.java:51 ) в jetbrains.исход.люсинэ.Вывод exodusindexout.(ExodusIndexOutput.kt:33) в jetbrains.исход.люсинэ.ExodusDirectory.createOutput(ExodusDirectory.kt:67) в org.apache.lucene.store.LockValidatingDirectoryWrapper.createOutput(LockValidatingDirectoryWrapper.java:44) в org.apache.lucene.store.TrackingDirectoryWrapper.createOutput(TrackingDirectoryWrapper.java:43) в org.apache.lucene.codecs.сжатие.Сжатиеstoredfieldswriter.(CompressingStoredFieldsWriter.java:112) в org.apache.lucene.codecs.сжатие.CompressingStoredFieldsFormat.fieldsWriter(CompressingStoredFieldsFormat.java:128) в org.apache.lucene.кодеки.lucene50.Lucene50StoredFieldsFormat.fieldsWriter(Lucene50StoredFieldsFormat.java:183) в org.apache.lucene.индекс.StoredFieldsConsumer.initStoredFieldsWriter(StoredFieldsConsumer.java:39) в org.apache.lucene.индекс.StoredFieldsConsumer.startDocument(StoredFieldsConsumer.java:46) в org.apache.lucene.индекс.DefaultIndexingChain.startStoredFields(DefaultIndexingChain.java:355) в org.апачи.lucene.индекс.DefaultIndexingChain.processDocument(DefaultIndexingChain.java:391) в org.apache.lucene.индекс.DocumentsWriterPerThread.updateDocument(DocumentsWriterPerThread.java:251) в org.apache.lucene.индекс.DocumentsWriter.updateDocument(DocumentsWriter.java:494) в org.apache.lucene.индекс.IndexWriter.updateDocument(IndexWriter.java:1609) в org.apache.lucene.индекс.IndexWriter.addDocument(IndexWriter.java:1228)

Ответ №1:

Xodus — это транзакционная база данных, поэтому для ее работы требуется транзакция как для чтения, так и для записи. Для LuceneDirectory требуется создать контекстную среду, используйте ее для создания транзакций.