1

We are using Solr version 6.4.

By submitting documents through the Solr web interface, I am able to add documents to our Solr index that are nested to arbitrary depth. We are only interested in adding documents nested to the grandchild level, as queries on nested documents get pretty complicated. An example document would look like this.

{
  "record_type_id": 1,
  "title": "Really good book",
  "author": "Jane Doe",
  "_childDocuments_": [
    {
      "record_type_id": 2,
      "section_title": "A section title"
      "_childDocuments_": [
        {
          "record_type_id": 3,
          "section_title": "A subsection title"
        },
        {
          "record_type_id": 3,
          "section_title": "Another subsection title"
        }
      ]
    }
}

Then we have some Java objects like this:

public class SolrRootDoc {
    private Integer recordTypeId;
    private String title;
    private String author;

    @Field(child = true)
    private List<SolrChildDoc> childDocuments;

    public Integer getRecordTypeId() {
        return recordTypeId;
    }

    @Field("record_type_id")
    public void setRecordTypeId(final Integer recordTypeId) {
        this.recordTypeId = recordTypeId;
    }

    public String getTitle() {
        return title;
    }

    @Field("title")
    public void setTitle(final String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    @Field("author")
    public void setAuthor(final String author) {
        this.author = author;
    }

    public List<SolrChildDoc> getChildDocuments() {
        return childDocuments;
    }

    public void setChildDocuments(final List<SolrChildDoc> childDocuments) {
        this.childDocuments = childDocuments;
    }
}


public class SolrChildDoc {
    private Integer recordTypeId;
    private String sectionTitle;

    @Field(child = true)
    private List<SolrChildDoc> childDocuments;

    public Integer getRecordTypeId() {
        return recordTypeId;
    }

    @Field("record_type_id")
    public void setRecordTypeId(final Integer recordTypeId) {
        this.recordTypeId = recordTypeId;
    }

    public String setSectionTitle() {
        return sectionTitle;
    }

    @Field("section_title")
    public void setSectionTitle(final String sectionTitle) {
        this.sectionTitle = sectionTitle;
    }

    public List<SolrChildDoc> getChildDocuments() {
        return childDocuments;
    }

    public void setChildDocuments(final List<SolrChildDoc> childDocuments) {
        this.childDocuments = childDocuments;
    }
}

When I run a unit test that tries to load these classes with DocumentObjectBinder. I get the following error.

java.lang.StackOverflowError at java.security.AccessController.doPrivileged(Native Method) at org.apache.solr.client.solrj.beans.DocumentObjectBinder.collectInfo(DocumentObjectBinder.java:143) at org.apache.solr.client.solrj.beans.DocumentObjectBinder.getDocFields(DocumentObjectBinder.java:123) at org.apache.solr.client.solrj.beans.DocumentObjectBinder.access$400(DocumentObjectBinder.java:38) at org.apache.solr.client.solrj.beans.DocumentObjectBinder$DocField.populateChild(DocumentObjectBinder.java:317) at org.apache.solr.client.solrj.beans.DocumentObjectBinder$DocField.storeType(DocumentObjectBinder.java:243) at org.apache.solr.client.solrj.beans.DocumentObjectBinder$DocField.(DocumentObjectBinder.java:183)

The "at" lines in this error repeat. It seems pretty clear the recursion is eating up the stack. If I remove the childDocuments property from the SolrChildDoc class, the error disappears.

Is it possible to represent Solr documents nested to an arbitrary level with the @Field annotation and DocumentObjectBinder? How would I do that without triggering a StackOverflowError?

k-den
  • 853
  • 13
  • 28

0 Answers0