2016-05-15 1 views
3

従業員Beanクラス:SOLRJ-6.0.0:Beanオブジェクトの仲間リストがnullポインタ例外を与えているBeanオブジェクトの挿入

public class Employee2 { 

    private String id; 
    private String name; 
    private String designation; 
    private double salary; 
    private double totalExperience; 
// private Address2 address2; 
    private Collection<Technology2> technologies2; 
    private String content_type = "employee2"; 

    public Employee2() { 
     super(); 
    } 

    public Employee2(String id, String name, String designation, double salary, double totalExperience, 
      Collection<Technology2> technologies2) { 
     super(); 
     this.id = id; 
     this.name = name; 
     this.designation = designation; 
     this.salary = salary; 
     this.totalExperience = totalExperience; 
//  this.address2 = address2; 
     this.technologies2 = technologies2; 
    } 

    /** 
    * @return the id 
    */ 
    public String getId() { 
     return id; 
    } 

    /** 
    * @param id the id to set 
    */ 
    @Field (value = "id") 
    public void setId(String id) { 
     this.id = id; 
    } 

    /** 
    * @return the name 
    */ 
    public String getName() { 
     return name; 
    } 

    /** 
    * @param name the name to set 
    */ 
    @Field (value = "name") 
    public void setName(String name) { 
     this.name = name; 
    } 

    /** 
    * @return the designation 
    */ 
    public String getDesignation() { 
     return designation; 
    } 

    /** 
    * @param designation the designation to set 
    */ 
    @Field (value = "designation_s") 
    public void setDesignation(String designation) { 
     this.designation = designation; 
    } 

    /** 
    * @return the salary 
    */ 
    public double getSalary() { 
     return salary; 
    } 

    /** 
    * @param salary the salary to set 
    */ 
    @Field (value = "salary_d") 
    public void setSalary(double salary) { 
     this.salary = salary; 
    } 

    /** 
    * @return the totalExperience 
    */ 
    public double getTotalExperience() { 
     return totalExperience; 
    } 

    /** 
    * @param totalExperience the totalExperience to set 
    */ 
    @Field (value = "totalExperience_d") 
    public void setTotalExperience(double totalExperience) { 
     this.totalExperience = totalExperience; 
    } 

// /** 
//  * @return the address2 
//  */ 
// public Address2 getAddress() { 
//  return address2; 
// } 
// 
// /** 
//  * @param address2 the address2 to set 
//  */ 
// @Field (child = true) 
// public void setAddress(Address2 address2) { 
//  this.address2 = address2; 
// } 

    /** 
    * @return the technologies2 
    */ 
    public Collection<Technology2> getTechnologies2() { 
     return technologies2; 
    } 

    /** 
    * @param technologies2 the technologies2 to set 
    */ 
    @Field (child = true) 
    public void setTechnologies2(Collection<Technology2> technologies2) { 
     this.technologies2 = technologies2; 
    } 

    /** 
    * @return the content_type 
    */ 
    public String getContent_type() { 
     return content_type; 
    } 

    /** 
    * @param content_type the content_type to set 
    */ 
    @Field(value="content_type_t") 
    public void setContent_type(String content_type) { 
     this.content_type = content_type; 
    } 

    /* (non-Javadoc) 
    * @see java.lang.Object#toString() 
    */ 
    @Override 
    public String toString() { 
     return "Employee2 [id=" + id + ", name=" + name + ", designation=" + designation + ", salary=" + salary + 
       ", totalExperience=" + totalExperience + ", technologies2=" + this.getTechnologies(technologies2) + 
       ", content_type=" + content_type + "]"; 
    } 

    private String getTechnologies(Collection<Technology2> technologies2) { 
     String strTechnologies = "["; 
     for(Technology2 technology: technologies2) { 
      strTechnologies = strTechnologies+technology.toString(); 
     } 
     return strTechnologies+"]"; 
    } 

} 

技術Beanクラス:

public class Technology2 { 

    private String id; 
    private String name; 
    private int experience; 
    private boolean certified; 
    private String content_type = "technology2"; 


    public Technology2() { 
     super(); 
    } 

    public Technology2(String id, String name, int experience, boolean certified) { 
     super(); 
     this.id = id; 
     this.name = name; 
     this.experience = experience; 
     this.certified = certified; 
    } 

    /** 
    * @return the id 
    */ 
    public String getId() { 
     return id; 
    } 
    /** 
    * @param id the id to set 
    */ 
    @Field(value="id") 
    public void setId(String id) { 
     this.id = id; 
    } 
    /** 
    * @return the name 
    */ 
    public String getName() { 
     return name; 
    } 
    /** 
    * @param name the name to set 
    */ 
    @Field(value="name") 
    public void setName(String name) { 
     this.name = name; 
    } 
    /** 
    * @return the experience 
    */ 
    public int getExperience() { 
     return experience; 
    } 
    /** 
    * @param experience the experience to set 
    */ 
    @Field(value="experience_i") 
    public void setExperience(int experience) { 
     this.experience = experience; 
    } 
    /** 
    * @return the certified 
    */ 
    public boolean getCertified() { 
     return certified; 
    } 
    /** 
    * @param certified the certified to set 
    */ 
    @Field(value="certified_b") 
    public void setCertified(boolean certified) { 
     this.certified = certified; 
    } 
    /** 
    * @return the content_type 
    */ 
    public String getContent_type() { 
     return content_type; 
    } 
    /** 
    * @param content_type the content_type to set 
    */ 
    @Field(value="content_type_t") 
    public void setContent_type(String content_type) { 
     this.content_type = content_type; 
    } 
    /* (non-Javadoc) 
    * @see java.lang.Object#toString() 
    */ 
    @Override 
    public String toString() { 
     return "Technology2 [id=" + id + ", name=" + name + ", experience=" + experience + ", certified=" + certified + 
       ", content_type=" + content_type + "]"; 
    } 

Employee BeanにネストされたAddress Beanがある場合、Bean挿入メソッドが正常に機能していますが、この例ではEmployee BeanがCollection of Technology Beanをネストしていますが、これは例外として以下の行で発生しています

UpdateResponse response = solrClient.addBean(bean);

挿入方法:

public <T> boolean insert (T bean) { 
     try { 
      UpdateResponse response = solrClient.addBean(bean); 
      System.out.println("insert bean ElapsedTime: " + response.getElapsedTime()); 
      solrClient.commit(); 
      return true; 
     } catch (IOException | SolrServerException e) { 
      e.printStackTrace(); 
     } 
     return false; 
    } 
ここ

それはヌル・ポインタ例外を返すは、以下Employee2

Employee2 [ID = EE130S、名前= Vulrp、指定= NjLtKのtoString値です。 、 salary = 127334.59626719051、totalExperience = 49.989444163266164、 technologies2 = [Technology2 [id = 0TE130S、name = uyIOFlh、experience = 21、 certified = true、content_type = technology2] Technology2 [ID = 1TE130S、 、名前= FmZJak、体験= 43、認定= false、 content_type = technology2] Technology2 [ID = 2TE130S、name = ddJbOXg、 エクスペリエンス= 11、認定= false、content_type = technology2] Technology2 [ ID = 3TE130S、名前= rIxumUe、経験= 5、認定=真、 CONTENT_TYPE = technology2]]、CONTENT_TYPE = employee2]

それは、例外の下の原因となっている。

java.lang.NullPointerException 
    at org.apache.solr.client.solrj.beans.DocumentObjectBinder$DocField.storeType(DocumentObjectBinder.java:243) 
    at org.apache.solr.client.solrj.beans.DocumentObjectBinder$DocField.<init>(DocumentObjectBinder.java:183) 
    at org.apache.solr.client.solrj.beans.DocumentObjectBinder.collectInfo(DocumentObjectBinder.java:144) 
    at org.apache.solr.client.solrj.beans.DocumentObjectBinder.getDocFields(DocumentObjectBinder.java:123) 
    at org.apache.solr.client.solrj.beans.DocumentObjectBinder.toSolrInputDocument(DocumentObjectBinder.java:76) 
    at org.apache.solr.client.solrj.SolrClient.addBean(SolrClient.java:277) 
    at org.apache.solr.client.solrj.SolrClient.addBean(SolrClient.java:259) 
    at com.opteamix.buildpal.poc.SampleSolrDAO.insert(SampleSolrDAO.java:62) 
    at com.opteamix.buildpal.poc.SampleSolrDAOTest.testEmployees2Insert(SampleSolrDAOTest.java:94) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at junit.framework.TestCase.runTest(TestCase.java:168) 
    at junit.framework.TestCase.runBare(TestCase.java:134) 
    at junit.framework.TestResult$1.protect(TestResult.java:110) 
    at junit.framework.TestResult.runProtected(TestResult.java:128) 
    at junit.framework.TestResult.run(TestResult.java:113) 
    at junit.framework.TestCase.run(TestCase.java:124) 
    at junit.framework.TestSuite.runTest(TestSuite.java:243) 
    at junit.framework.TestSuite.run(TestSuite.java:238) 
    at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 

答えて

5

Inserti Beanのリストを関連付けるBeanオブジェクトのonは、現在期待どおりに動作しています。

最後に、solrj6.0.0ソースコードを調べたところ、解決方法が見つかりました。実際にはsolrj6.0.0にバグがあります。それは次のとおりです。 私たちは以下のようにEmployee2 Bean内のsetメソッドで@Field注釈を与えている場合:

/** 
    * @param technologies2 the technologies2 to set 
    */ 
    @Field (child = true) 
    public void setTechnologies2(Collection<Technology2> technologies2) { 
     this.technologies2 = technologies2; 
    } 

そして、それは技術のリストを集約当社Employee2豆挿入するための例外を発生させています。sorljコードからバグのようだとして:

DocumentObjectBinderの

ネストされたDocFieldクラスはimplementionの下にあります。我々は、したがって、ここでセッターで(子=真)@Fieldを注釈を付けたよう

public DocField(AccessibleObject member) { 
     if (member instanceof java.lang.reflect.Field) { 
     field = (java.lang.reflect.Field) member; 
     } else { 
     setter = (Method) member; 
     } 
     annotation = member.getAnnotation(Field.class); 
     storeName(annotation); 
     storeType(); 

     // Look for a matching getter 
     if (setter != null) { 
     String gname = setter.getName(); 
     if (gname.startsWith("set")) { 
      gname = "get" + gname.substring(3); 
      try { 
      getter = setter.getDeclaringClass().getMethod(gname, (Class[]) null); 
      } catch (Exception ex) { 
      // no getter -- don't worry about it... 
      if (type == Boolean.class) { 
       gname = "is" + setter.getName().substring(3); 
       try { 
       getter = setter.getDeclaringClass().getMethod(gname, (Class[]) null); 
       } catch(Exception ex2) { 
       // no getter -- don't worry about it... 
       } 
      } 
      } 
     } 
     } 
    } 

この場合、フィールドにだから、今のようにIフィールド・レベルで@Field注釈を注釈AM()メソッド

private void storeType() { 
     if (field != null) { 
     type = field.getType(); 
     } else { 
     Class[] params = setter.getParameterTypes(); 
     if (params.length != 1) { 
      throw new BindingException("Invalid setter method. Must have one and only one parameter"); 
     } 
     type = params[0]; 
     } 

     if (type == Collection.class || type == List.class || type == ArrayList.class) { 
     isList = true; 
     if (annotation.child()) { 
      populateChild(field.getGenericType()); 
     } else { 
      type = Object.class; 
     } 
     } else if (type == byte[].class) { 
     //no op 
     } else if (type.isArray()) { 
     isArray = true; 
     if (annotation.child()) { 
      populateChild(type.getComponentType()); 
     } else { 
      type = type.getComponentType(); 
     } 
     } else if (type == Map.class || type == HashMap.class) { //corresponding to the support for dynamicFields 
     if (annotation.child()) throw new BindingException("Map should is not a valid type for a child document"); 
     isContainedInMap = true; 
     //assigned a default type 
     type = Object.class; 
     if (field != null) { 
      if (field.getGenericType() instanceof ParameterizedType) { 
      //check what are the generic values 
      ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType(); 
      Type[] types = parameterizedType.getActualTypeArguments(); 
      if (types != null && types.length == 2 && types[0] == String.class) { 
       //the key should always be String 
       //Raw and primitive types 
       if (types[1] instanceof Class) { 
       //the value could be multivalued then it is a List, Collection, ArrayList 
       if (types[1] == Collection.class || types[1] == List.class || types[1] == ArrayList.class) { 
        type = Object.class; 
        isList = true; 
       } else { 
        //else assume it is a primitive and put in the source type itself 
        type = (Class) types[1]; 
       } 
       } else if (types[1] instanceof ParameterizedType) { //Of all the Parameterized types, only List is supported 
       Type rawType = ((ParameterizedType) types[1]).getRawType(); 
       if (rawType == Collection.class || rawType == List.class || rawType == ArrayList.class) { 
        type = Object.class; 
        isList = true; 
       } 
       } else if (types[1] instanceof GenericArrayType) { //Array types 
       type = (Class) ((GenericArrayType) types[1]).getGenericComponentType(); 
       isArray = true; 
       } else { //Throw an Exception if types are not known 
       throw new BindingException("Allowed type for values of mapping a dynamicField are : " + 
        "Object, Object[] and List"); 
       } 
      } 
      } 
     } 
     } else { 
     if (annotation.child()) { 
      populateChild(type); 
     } 
     } 
    } 

storeTypeによってNULLポインタ例外の原因となっているヌルでありますむしろセッターでより:

@Field (child = true) 
    private Collection<Technology2> technologies2; 

だから今、このような豆の挿入は予想通り、私は結果の下に取得しています取得するには、成功している:

Employee2 [ID = E3、名前= KzWhg、指定= aTDiu 、 給与= 190374.70126209356、totalExperience = 2.0293696897450584、 technologies2 = [Technology2 [ID = 0T3、名前= nxTdufv、経験= 46、 認定=偽、CONTENT_TYPE = technology2] Technology2 [ID = 1T3、 名= waSMXpf、経験= 26、certified = false、 content_type = technology2] Technology2 [id =技術2 [ID = 3T3、名前= VnidjyI、経験= 21、認定= true、 content_type = technology2] Technology2 [id = 4T3、name] = 0、認定= false、 content_type = technology2]]、content_type = employee2] Employee2 [id = 5T3、name = cpUfgrY] E4、 名= xeKOY、指定= WfPSm、給与= 169700.53869292728、 totalExperience = 22.047282596410284、technologies2 = [technology2 [ID = 0T4、名前= rleygcW、経験= 30、認定=真、 CONTENT_TYPE = technology2] technology2 [ID = 1T4、名前= yxjHrxV、 経験= 27、cerテクノロジー2 [ID = 3T4、名前= RDhoIJw、 経験= 22、認定= false、技術2 [ID = 2T4、名前= czjHAEE、経験= 31、認定= false、 content_type = technology2] Employee2 [id = E5、 name = tIWuY、designation = WikuL、content_type = technology2]、content_type = technology2]給与= 41462.47225086359、 totalExperience = 13.407976384902403、technologies2 = [Technology2 [ID = 0T5、名前= CDCMunq、経験= 6、認定=偽、 CONTENT_TYPE = technology2] Technology2 [ID = 1T5、名前= NmkADyB、 経験= 31 、certified = false、content_type = technology2] Technology2Employee2 [id = E6、 name = YluDp、designation = EtFqG、salary = 159724.66206009954、 totalExperience [id = 2T5、name = IhXnLfc、experience = 9、certified = true、 content_type = technology2] = 26。テクノロジー2 [ID = 1T6、名前= arTNoHj、 経験= 44、認定= true、content_type = 0、技術2 [ID = 0T6、 名前= mFvKDIK、経験= 33、認定= false、 content_type =技術2]技術2 [ID = 3T6、名前= ZTphSVn、 経験= 13、認定=真、content_type =技術2] [ID2T6、名前= KYMseTW、経験= 34、認定=偽、 content_type = technology2]技術2 ] 、 CONTENT_TYPE = employee2] employee2 [ID = E7、名前= qMkKG、 指定= SQHCo、給与= 111861.53447042785、 totalExperience = 13.29234679211927、technologies2 = [Technology2 [ID = 0T7、 名= PTKxjFl、経験= 23、認定= false、 content_type = technology2]テクノ技術2 [ID = 2T7、名前= eekPYPN、経験= 40、認定= true、 content_type = technology2] Technology2 [id2] [ID = 1T7、名前= gJfxbto、 経験= 17、認定= true、content_type =技術2 [id = 5T7、名前= aRdsEag、 経験= 40、認定= true、content_type = technology2]テクノロジー2 [ID = 4T7、名前= loDFVyM、経験= 40、認定= true、 content_type =名前= xPXNaDV、= 0、認定=偽、CONTENT_TYPE = technology2 経験]、 CONTENT_TYPE = employee2] Employee2 [ID = E8、名前= WyNsf、 指定= TtanH、給与= 107942.13641940584、 totalExperience = 47.036469485140984、technologies2 = [技術2 [ID = 0T8、名前= kakGXqh、経験技術2 [id = 2T8、name = rNzwcdQ、experience = 31、experience = 9、certified = true、content_type = technology2] Employee2 [id = E9、name = EzuLC、 ]、[、content_type = employee2][ID = 0T9、名前= GmvOUWp、経験= 5、認定= true、 content_type = technology2] Technology2 [id = 1T9、name = ZWyvRxk、 エクスペリエンス= 24、認定= false、content_type = technolテクノロジー2 [ID = 3T9、名前= NFknqJj、 経験= 29、認定=真、content_type =技術2]] 、 CONTENT_TYPE = employee2] employee2 [ID = E10、名前= quFKB、 指定= eUoBJ、給与= 198332.3270496455、 totalExperience = 14.035578311712438、technologies2 = [Technology2 [ID = 0T10、名前= MOXduwi、経験= 49、認定=偽、 content_type = technology2] Technology2 [id = 1T10、name = LpXGRvn、 エクスペリエンス= 28、認定= false、content_type = technology2] Technology2 [id = 2T10、name = QeAOjIp、experience = 3、certified = true、 content_type = technology2] Technology2 [id = 3T10、name = aVx認定GhOV、 経験= 34、=真、CONTENT_TYPE = technology2] Technology2 [ID = 4T10、名前= fbSaBUm、経験= 42、認定=真、 CONTENT_TYPE = technology2]、CONTENT_TYPE = employee2]

私はJIRAでコードの不具合を提起しました: https://issues.apache.org/jira/browse/SOLR-9112

3

でもSolrjコードは複数の子をBeanとして挿入することをサポートしていません。例外:複数の子がサポートされていません。しかし、他の方法では、複数のBeanを集約するBeanの挿入は、SolrInputクラスによって挿入/索引付けできます。

+2

はい、そのために私はバグを鳴らします。まあ、SolrJコードごとに、1つ以上の子がある場合は、solrClient.addBean(bean);手動の例外による方法:それ以上の子がサポートされていない。しかし、SolrInputDocumentでは複数の子を追加できます。私は、複数のBeanを関連付けるBeanの挿入をサポートするリフレクションコードを書くことを考えています。リフレクションコードはこのURLに記述されているコードの種類を処理します:[https://github.com/ lucidworks/solrj-nested-docs/blob/master/NestedDocs2.java] –

+0

はい、それは良いようです。 – Coder

+1

http://stackoverflow.com/questions/37677538/how-to-insert-bean-object-which-has-many-child-bean-in-solrj/37678532#37678532 –

関連する問題