我们能否为Spring Batch的ExecutionContext生成Lucene IndexWriter序列化?

时间:2016-09-27 06:33:46

标签: java serialization lucene spring-batch

此问题与my another SO question有关。

要在分区步骤的持续时间内保持IndexWriter处于打开状态,我想在IndexWriter的分区程序中添加ExecutionContext,然后在StepExecutionListenerSupport的{​​{1}} {{}}中关闭afterStep(StepExecution stepExecution) 1}}方法。

我在这种方法中遇到的挑战是ExecutionContext需要对象可序列化。

根据这两个问题Q1Q2 - 它似乎不可行,因为我无法在自定义编写器中添加no-arg构造函数,因为IndexWriter没有任何no - arg构造函数。

    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();
        }

    }

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

有没有办法实现这个目标?

2 个答案:

答案 0 :(得分:0)

您始终可以添加无参数构造函数。

E.g:

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);

因此,将这些值添加为默认值可以解决问题。也许然后为分析器和MaxFieldLength添加getter和setter方法,这样你就可以在以后阶段控制它。

答案 1 :(得分:0)

我不确定如何在Spring Batch中使用此语法,ExecutionContextStepExecutionListenerSupport中返回非空对象。

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的实例,分区步骤块与编写器一起工作,getLuceneIndexWriter()然后在StepExecutionListenerSupport中,我关闭了这个编写器。

这样我的spring批处理分区步骤就可以使用Lucene Index Writer Object的单个实例。

我希望如果尝试对getLuceneIndexWriter()获得的编写器执行操作,我将获得NullPointer,但这并不会发生(尽管它是transient)。我不确定为什么会这样,但确实如此。

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