+1

Good question, my use of Solr would benefit from nested annotated beans as well.

Awaiting the reply,

Thom


On 2010-06-03, at 1:35 PM, Peter Hanning wrote:

> 
> When modeling documents with a lot of fields (hundreds) the bean class used
> with SolrJ to interact with the Solr index tends to get really big and
> unwieldy. I was hoping that it would be possible to extract groups of
> properties into nested beans and move the @Field annotations along.
> 
> Basically, I want to refactor something like the following:
> 
>  // Imports have been omitted for this example.
>  public class TheBigOne
>  {
>    @Field("UniqueKey")
>    private String uniqueKey;
>    @Field("Name_en")
>    private String name_en;
>    @Field("Name_es")
>    private String name_es;
>    @Field("Name_fr")
>    private String name_fr;
>    @Field("Category")
>    private String category;
>    @Field("Color")
>    private String color;
>    // Additional properties, getters and setters have been omitted for this
> example.
>  }
> 
> into something like the following:
> 
>  // Imports have been omitted for this example.
>  public class TheBigOne
>  {
>    @Field("UniqueKey")
>    private String uniqueKey;
>    private Names names = new Names();
>    private Classification classification = new Classification();
>    // Additional properties, getters and setters have been omitted for this
> example.
>  }
> 
>  // Imports have been omitted for this example.
>  public class Names
>  {
>    @Field("Name_en")
>    private String name_en;
>    @Field("Name_es")
>    private String name_es;
>    @Field("Name_fr")
>    private String name_fr;
>    // Additional properties, getters and setters have been omitted for this
> example.
>  }
> 
>  // Imports have been omitted for this example.
>  public class Classification
>  {
>    @Field("Category")
>    private String category;
>    @Field("Color")
>    private String color;
>    // Additional properties, getters and setters have been omitted for this
> example.
>  }
> 
> This did not work however as the DocumentObjectBinder does not seem to walk
> the nested object graph. Am I doing something wrong, or is this not
> supported?
> 
> I see JIRA tickets 1129 and 1357 could alleviate this issue somewhat for the
> Name* fields once 1.5 comes out. Still, it would be great to be able to nest
> beans without using dynamic names in the field annotations like in the
> Classification example above.
> 
> 
> As a quick and naive test I tried to change the DocumentObjectBinder's
> collectInfo method to something like the following:
> 
>  private List<DocField> collectInfo(Class clazz) {
>    List<DocField> fields = new ArrayList<DocField>();
>    Class superClazz = clazz;
>    ArrayList<AccessibleObject> members = new ArrayList<AccessibleObject>();
>    while (superClazz != null && superClazz != Object.class) {
>      members.addAll(Arrays.asList(superClazz.getDeclaredFields()));
>      members.addAll(Arrays.asList(superClazz.getDeclaredMethods()));
>      superClazz = superClazz.getSuperclass();
>    }
>    for (AccessibleObject member : members) {
>      if (member.isAnnotationPresent(Field.class)) {
>        member.setAccessible(true);
>        fields.add(new DocField(member));
>      } // BEGIN changes
>      else { // A quick test supporting only Field, not Method and others
>        if (member instanceof java.lang.reflect.Field) {
>          java.lang.reflect.Field field = (java.lang.reflect.Field) member;
>          fields.addAll(collectInfo(field.getType()));
>        }
>      } // END changes
>    }
>    return fields;
>  }
> 
> This worked in that SolrJ started walking down into nested beans, checking
> for and handling @Field annotations in the nested beans. However, when
> trying to retrieve the values of the fields in the nested beans, SolrJ still
> tried to look for them in the main bean as far as I can tell.
> 
> ERROR 2010-06-02 09:28:35,326 (main) () (SolrIndexer.java:335 main) -
> Exception encountered:
> java.lang.RuntimeException: Exception while getting value: private
> java.lang.String Names.Name_en
>        at
> org.apache.solr.client.solrj.beans.DocumentObjectBinder$DocField.get(DocumentObjectBinder.java:377)
>        at
> org.apache.solr.client.solrj.beans.DocumentObjectBinder.toSolrInputDocument(DocumentObjectBinder.java:71)
>        at
> org.apache.solr.client.solrj.SolrServer.addBeans(SolrServer.java:56)
> ...
> Caused by: java.lang.IllegalArgumentException: Can not set java.lang.String
> field Names.Name_en to TheBigOne
>        at
> sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
>        at
> sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
>        at
> sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:37)
>        at
> sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:18)
>        at java.lang.reflect.Field.get(Field.java:358)
>        at
> org.apache.solr.client.solrj.beans.DocumentObjectBinder$DocField.get(DocumentObjectBinder.java:374)
>        ... 7 more
> 
> My conclusion is that the @Field annotation can presently only be put in the
> main bean and nested beans are not supported. It seems that more more than a
> simple patch is required to rewrite how SolrJ collects document fields from
> nested beans.
> 
> Shall I go ahead and create a JIRA ticket with this information?
> 
> Best Regards,
> Peter
> 
> -- 
> View this message in context: 
> http://lucene.472066.n3.nabble.com/Does-SolrJ-support-nested-annotated-beans-tp868375p868375.html
> Sent from the Solr - User mailing list archive at Nabble.com.
> 

Reply via email to