+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. >