提问者:小点点

我们可以使Lucene IndexWriter可序列化为Spring Batch的ExecutionContext吗?


这个问题与我的另一个SO问题有关。

为了在分区步骤期间保持IndexWriter打开,我想在partitioner的ExecutionContext中添加IndexWriter,然后在步骤(StepExecutionstepExecution)之后的StepExecutionListenerSupport方法中关闭。

我在这种方法中面临的挑战是ExectionContext需要对象是可序列化的。

鉴于这两个问题,Q1、Q2——这似乎不可行,因为我不能在自定义编写器中添加无参数构造函数,因为IndexWriter没有任何无参数构造函数。

    public class CustomIndexWriter extends IndexWriter implements Serializable {
    /*
private Directory d;
    private IndexWriterConfig conf;


        public CustomIndexWriter(){
            super();
            super(this.d, this.conf);
        }
        */
        public CustomIndexWriter(Directory d, IndexWriterConfig conf) throws IOException {
            super(d, conf);
        }

        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException{
            input.defaultReadObject();
        }

        private void writeObject(ObjectOutputStream output) throws IOException, ClassNotFoundException {
            output.defaultWriteObject();
        }

    }

在上面的代码中,我无法添加显示为注释的构造函数,因为超级类中不存在no-arg构造函数,并且无法访问Super之前的this字段。

有办法做到这一点吗?


共2个答案

匿名用户

您总是可以添加无参数的构造函数。

例如:

public class CustomWriter extends IndexWriter implements Serializable {
    private Directory lDirectory;
    private IndexWriterConfig iwConfig;

    public CustomWriter() {
        super();
        // Assign default values
        this(new Directory("." + System.getProperty("path.separator")), new IndexWriterConfig());
    }

    public CustomWriter(Directory dir, IndexWriterConfig iwConf) {
        lDirectory = dir;
        iwConfig = iwConf;
    }

    public Directory getDirectory() { return lDirectory; }

    public IndexWriterConfig getConfig() { return iwConfig; }

    public void setDirectory(Directory dir) { lDirectory = dir; }

    public void setConfig(IndexWriterConfig conf) { iwConfig = conf; }

    // ...
}

编辑:

看了一下我自己的代码(使用Lucene。Net),IndexWriter需要一个分析器和一个MaxFieldLength。

所以超级调用看起来像这样:

super(new Directory("." + System.getProperty("path.separator")), new StandardAnalyzer(), MaxFieldLength.UNLIMITED);

所以添加这些值作为默认值应该可以解决这个问题。也许可以为analyzer和MaxFieldLength添加getter和setter方法,这样您就可以在以后的阶段对其进行控制。

匿名用户

我不知道如何,但这种语法在Spring Batch中工作,并且ExectionContextStepExectionListener Support中返回一个非空对象。

public class CustomIndexWriter implements Serializable {


    private static final long serialVersionUID = 1L;

    private transient IndexWriter luceneIndexWriter;

    public CustomIndexWriter(IndexWriter luceneIndexWriter) {
         this.luceneIndexWriter=luceneIndexWriter;
    }

    public IndexWriter getLuceneIndexWriter() {
        return luceneIndexWriter;
    }

    public void setLuceneIndexWriter(IndexWriter luceneIndexWriter) {
        this.luceneIndexWriter = luceneIndexWriter;
    }


}

我将CustomIndexWriter的实例放在steppartitioner中,分区的步骤块通过执行,getLuceneIndexWriter()与writer一起工作,然后在StepExecutionListenerSupport中,我关闭了这个编写器。

这样,我的Spring批处理分区步骤与Lucene Index Writer对象的单个实例一起工作。

我希望在尝试对< code > getLuceneIndexWriter()获得的writer执行操作时会得到一个NullPointer,但这并没有发生(尽管它是< code >瞬态的)。我不知道为什么会这样,但确实如此。

对于SpringBatch作业元数据,我使用的是内存存储库,而不是基于数据库的存储库。不确定一旦我开始使用db作为元数据,这是否会继续工作。