当前位置: 首页 > 知识库问答 >
问题:

LockObtainFailedException和索引器的实例化

罗宪
2023-03-14

我正在开发一个用于信息检索的web应用程序(使用JSF),我正在使用Lucene读取和索引file.pdf。我读了前面的一个关于LockObtainFailedException的问题(在new IndexWriter()处),但是我仍然无法解决我的问题,所以我将简要地解释一下。

我有一个managedBean使用以下方法对文档进行索引:

     @ManagedBean
      @RequestScoped
      public class managedBeanIB{


       @EJB
       private Indexer indexer;


       private Part file;;
       private long ISBN;
       private String author;
       private String title;
       private String content; // getter and setter for each field

       ...

        public String add() throws IOException{


                indexer = new Indexer();
                InputStream is = file.getInputStream(); 
                PDDocument doc = PDDocument.load(is);
                contenuto = new PDFTextStripper().getText(doc);
                doc.close();
                Book book = new Libro(ISBN,author,title,content);
                indexer.index(book);
                indexer.close();




                return "home";

   }
}//class
@Stateless
public class Indexer implements Serializable {


private static final String directory = "C:\\Users\\EngineFM\\Documents\\NetBeansProjects\\SIA\\SIA-ejb\\src\\resources\\index\\";

    public static final String ENG = "english";


    private IndexWriter iw;

    public Indexer() {



        try {
            if (iw == null) {


                iw = new IndexWriter(FSDirectory.open(new File(directory)),
                        new IndexWriterConfig(Version.LATEST, new EnglishAnalyzer()));

            }
        } catch (IOException ex) {
            System.out.println("something wrong");
            ex.printStackTrace();

        }

    }



    public void index(Book item) throws IOException{

        iw.deleteDocuments(new Term(Book.ID, String.valueOf(item.getISBN())));



        Document doc = new Document();


       doc.add(new LongField(Book.ID, item.getISBN(),Field.Store.YES));
       doc.add(new StringField(Book.AUTHOR, item.getAuthor(),Field.Store.YES));
       doc.add(new StringField(Book.TITLE, item.getTitle(),Field.Store.YES));
       doc.add(new TextField(Libro.CONTENT, item.getContent(),Field.Store.YES));



       iw.addDocument(doc);
       iw.commit();

    }

    public void close() throws IOException {
        iw.close();
    }

当我启动我的应用程序(主页)时,我注意到Indexer和我的托管bean一起被实例化了。然后我进入添加页面,我填写所有需要的信息,我点击“添加文档”。在这种情况下,Indexer再次实例化,但前面的锁仍然打开(我猜),所以文档没有存储,我有以下异常:

我怎样才能避免这种情况呢?我正在考虑unlock()方法(如https://lucene.apache.org/core/4_1_0/core/org/apache/lucene/index/indexwriter.html#close()中所建议的),但我不知道将其放置在何处。感谢任何帮助。

根据femtoRgon的建议,我尝试修改代码,以避免对每个add()操作进行实例化:

public String add() throws IOException{



                    InputStream is = file.getInputStream(); 
                    PDDocument doc = PDDocument.load(is);
                    contenuto = new PDFTextStripper().getText(doc);
                    doc.close();
                    Book book = new Libro(ISBN,author,title,content);
                    indexer.index(book);
                    indexer.close();




                    return "home";

       }

不幸的是,结果是相同的,并且在write.lock上似乎有一些冲突。我不知道怎么可能。可能是每个请求都重新生成bean,并且我有两个或更多的锁?是否应该更改@RequestScoped注释?

共有1个答案

居星阑
2023-03-14

我找到了解决我问题的办法。如前所述,这取决于托管bean的作用域。在@RequestScoped的情况下,为每个请求创建托管bean:在我的例子中,这意味着也为每个请求生成索引器。我在Indexer构造函数中对IndexWriter进行了实例化,因此,由于实例是在一开始(应用程序启动时)生成的,所以当我尝试计算请求时,它又生成了一次,并且在写锁上存在冲突问题。我在index()方法中解决了推迟IndexWriter的实例化问题。这里是我的代码:

 public void index(Book item) throws IOException{



        if (iw == null) {

                iw = new IndexWriter(FSDirectory.open(new File(directory)),
                        new IndexWriterConfig(Version.LATEST, new EnglishAnalyzer()));


            }


        iw.deleteDocuments(new Term(Book.ID, String.valueOf(item.getISBN())));



        Document doc = new Document();





       doc.add(new LongField(Book.ID, item.getISBN(),Field.Store.YES));
       doc.add(new StringField(Book.AUTHOR, item.getAuthor(),Field.Store.YES));
       doc.add(new StringField(Book.TITLE, item.getTitle(),Field.Store.YES));
       doc.add(new TextField(Book.CONTENT, item.getContent(),Field.Store.YES));




       iw.addDocument(doc);
       iw.commit();

    }

此外,我删除了指示

Indexer.Close()

from add()方法,因为只有在应用程序结束时才需要调用它。

 类似资料:
  • 本文向大家介绍Lucene实现索引和查询的实例讲解,包括了Lucene实现索引和查询的实例讲解的使用技巧和注意事项,需要的朋友参考一下 0引言 随着万维网的发展和大数据时代的到来,每天都有大量的数字化信息在生产、存储、传递和转化,如何从大量的信息中以一定的方式找到满足自己需求的信息,使之有序化并加以利用成为一大难题。全文检索技术是现如今最普遍的信息查询应用,生活中利用搜索引擎,在博客论坛中查找信息

  • 本文向大家介绍Oracle 分区索引介绍和实例演示,包括了Oracle 分区索引介绍和实例演示的使用技巧和注意事项,需要的朋友参考一下 分区索引(或索引分区)主要是针对分区表而言的。随着数据量的不断增长,普通的堆表需要转换到分区表,其索引呢,则对应的转换到分区索引。分区索引的好处是显而易见的。就是简单地把一个索引分成多个片断,在获取所需数据时,只需要访问更小的索引片断(块)即可实现。同时把分区放在

  • 本文向大家介绍oracle索引的测试实例代码,包括了oracle索引的测试实例代码的使用技巧和注意事项,需要的朋友参考一下 前言 在测试oracle索引性能时大意了,没有仔细分析数据特点,将情况特此记录下来。  需求:  对一张100w记录的表的 stuname列进行查询,测试在建立索引与不建立索引的区别. 以下是开始用的创建代码及执行效果.  1. 随机数据生成代码分析 --先分析以下上面的代码

  • 本文向大家介绍Python 获取numpy.array索引值的实例,包括了Python 获取numpy.array索引值的实例的使用技巧和注意事项,需要的朋友参考一下 举个例子: 我想获取其中值等于7的那个值的下标,以便于用于其他计算。 如果使用np.where,如: 运行结果是: 显然(array([7]),)中的数字7我是没法提取出来做运算的,这是一个tuple。 处理方法是: 运行结果为:

  • 本文向大家介绍MySQL的id关联和索引使用的实际优化案例,包括了MySQL的id关联和索引使用的实际优化案例的使用技巧和注意事项,需要的朋友参考一下 昨晚收到客服MM电话,一用户反馈数据库响应非常慢,手机收到load异常报警,登上主机后发现大量sql执行非常慢,有的执行时间超过了10s 优化点一: 表结构为: 执行计划: 分析该sql的执行计划,由于tran_id是表的主键,所以查询根据主键降序

  • 本文向大家介绍MySQL索引用法实例分析,包括了MySQL索引用法实例分析的使用技巧和注意事项,需要的朋友参考一下 本文实例分析了MySQL索引用法。分享给大家供大家参考,具体如下: MYSQL描述: 一个文章库,里面有两个表:category和article。category里面有10条分类数据。article里面有20万条。article里面有一个"article_category"字段是与c