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.