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