indexing - SOLRJ-6.0.0: Inserción de un objeto bean que asocia la lista del objeto bean dando una excepción de puntero nulo
nullpointerexception nested (2)
Incluso el Código Solrj no admite la inserción de múltiples hijos como un frijol. Da la excepción: hijo múltiple no compatible. Sin embargo, de otra manera, la inserción de un Bean que agrega beans múltiples puede ser insertada / indexada por la clase SolrInput.
Clase de Bean empleado:
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+"]";
}
}
Tecnología Bean Class:
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 + "]";
}
El método de inserción de frijoles está funcionando bien si el frijol empleado tiene un frijol de dirección anidado, sin embargo, en nuestro caso, el frijol empleado ha anidado la colección de tecnología Bean, está causando una excepción por debajo de la línea
Respuesta UpdateResponse = solrClient.addBean (bean);
Método de inserción:
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;
}
Aquí está devolviendo la excepción del puntero nulo, a continuación se muestra el valor toString de Employee2
Employee2 [id = EE130S, name = Vulrp, designation = NjLtK, salary = 127334.59626719051, totalExperience = 49.989444163266164, technologies2 = [Technology2 [id = 0TE130S, name = uyIOFlh, experience = 21, certified = true, content_type = technology2] Technology2 [id = 1TE130S, nombre = FmZJjak, experiencia = 43, certificado = falso, content_type = technology2] Technology2 [id = 2TE130S, name = ddJbOXg, experience = 11, certified = false, content_type = technology2] Technology2 [id = 3TE130S, name = rIxumUe , experience = 5, certified = true, content_type = technology2]], content_type = employee2]
Está causando la siguiente excepción :
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)
La inserción de un objeto bean que asocia la lista de bean funciona como se espera ahora.
Finalmente, después de buscar el código fuente solrj6.0.0, encontré la manera de resolverlo. En realidad, hay un error en solrj6.0.0. Es decir: si estamos dando @Field anotación en el método set en Employee2 bean como a continuación:
/**
* @param technologies2 the technologies2 to set
*/
@Field (child = true)
public void setTechnologies2(Collection<Technology2> technologies2) {
this.technologies2 = technologies2;
}
Entonces está causando una excepción para nuestra inserción de frijoles Employee2 que agrega una lista de tecnologías. Parece ser un error del código sorlj como:
La clase anidada DocField de DocumentObjectBinder tiene la siguiente implementación:
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...
}
}
}
}
}
}
Como anotamos @Field (child = true) en el setter, aquí en este caso el campo es nulo y está causando la excepción del puntero nulo por el método storeType ()
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);
}
}
}
Por lo tanto, a partir de ahora estoy anotando la anotación @Field en el campo en lugar de en setter:
@Field (child = true)
private Collection<Technology2> technologies2;
Entonces, ahora la inserción de tal bean es exitosa, al recuperar estoy obteniendo el resultado debajo de lo esperado:
Employee2 [id = E3, name = KzWhg, designation = aTDiu, salary = 190374.70126209356, totalExperience = 2.0293696897450584, technologies2 = [Technology2 [id = 0T3, name = nxTdufv, experience = 46, certified = false, content_type = technology2] Technology2 [id = 1T3, name = waSMXpf, experience = 26, certified = false, content_type = technology2] Technology2 [id = 2T3, name = jqNbZZr, experience = 30, certified = true, content_type = technology2] Technology2 [id = 3T3, name = VnidjyI , experience = 21, certified = true, content_type = technology2] Technology2 [id = 4T3, name = ulGnHFm, experience = 33, certified = false, content_type = technology2] Technology2 [id = 5T3, name = cpUfgrY, experience = 21, certified = falso, content_type = technology2]], content_type = employee2] Employee2 [id = E4, name = xeKOY, designation = WfPSm, salarial = 169700.53869292728, totalExperience = 22.047282596410284, technologies2 = [Technology2 [id = 0T4, name = rleygcW, experience = 30, certificado = verdadero, content_type = technology2] Technology2 [id = 1T4, name = yxjHrxV, experience = 27, certified = false, content_typ e = technology2] Technology2 [id = 2T4, name = czjHAEE, experience = 31, certified = false, content_type = technology2] Technology2 [id = 3T4, name = RDhoIJw, experience = 22, certified = false, content_type = technology2] Technology2 [ id = 4T4, name = UkbldDN, experience = 19, certified = false, content_type = technology2]], content_type = employee2] Employee2 [id = E5, name = tIWuY, designation = WikuL, salario = 41462.47225086359, totalExperience = 13.407976384902403, technologies2 = [Tecnología2 [id = 0T5, nombre = CDCMunq, experiencia = 6, certificado = falso, content_type = technology2] Technology2 [id = 1T5, name = NmkADyB, experience = 31, certified = false, content_type = technology2] Technology2 [id = 2T5 , name = IhXnLfc, experience = 9, certified = true, content_type = technology2]], content_type = employee2] Employee2 [id = E6, name = YluDp, designation = EtFqG, salarial = 159724.66206009954, totalExperience = 26.26819742766281, technologies2 = [Technology2 [ id = 0T6, name = mFvKDIK, experience = 33, certified = false, content_type = technology2] Technology2 [id = 1T6, name = arTNoHj, expe rience = 44, certified = true, content_type = technology2] Technology2 [id = 2T6, name = KYMseTW, experience = 34, certified = false, content_type = technology2] Technology2 [id = 3T6, name = ZTphSVn, experience = 13, certified = true, content_type = technology2]], content_type = employee2] Employee2 [id = E7, name = qMkKG, designation = SQHCo, salarial = 111861.53447042785, totalExperience = 13.29234679211927, technologies2 = [Technology2 [id = 0T7, name = PTKxjFl, experience = 23 , certified = false, content_type = technology2] Technology2 [id = 1T7, name = gJfxbto, experience = 17, certified = true, content_type = technology2] Technology2 [id = 2T7, name = eekPYPN, experience = 40, certified = true, content_type = technology2] Technology2 [id = 3T7, name = aRdsEag, experience = 40, certified = true, content_type = technology2] Technology2 [id = 4T7, name = loDFVyM, experience = 40, certified = true, content_type = technology2] Technology2 [id = 5T7, name = xPXNaDV, experience = 0, certified = false, content_type = technology2]], content_type = employee2] Employee2 [id = E8, name = WyNsf, designat ion = TtanH, salario = 107942.13641940584, totalExperience = 47.036469485140984, technologies2 = [Technology2 [id = 0T8, name = kakGXqh, experience = 14, certified = true, content_type = technology2] Technology2 [id = 1T8, name = ugwgdHy, experience = 9 , certified = true, content_type = technology2] Technology2 [id = 2T8, name = rNzwcdQ, experience = 31, certified = false, content_type = technology2] Technology2 [id = 3T8, name = ZBXUhuB, experience = 6, certified = true, content_type = technology2]], content_type = employee2] Employee2 [id = E9, name = EzuLC, designation = IXYGj, salary = 133064.4485190016, totalExperience = 16.075378097234232, technologies2 = [Technology2 [id = 0T9, name = GmvOUWp, experience = 5, certified = true, content_type = technology2] Technology2 [id = 1T9, name = ZWyvRxk, experience = 24, certified = false, content_type = technology2] Technology2 [id = 2T9, name = uWkTrfB, experience = 5, certified = false, content_type = technology2] Tecnología2 [id = 3T9, name = NFknqJj, experience = 29, certified = true, content_type = technology2]], content_type = employee2] Empl oyee2 [id = E10, name = quFKB, designation = eUoBJ, salario = 198332.3270496455, totalExperience = 14.035578311712438, technologies2 = [Technology2 [id = 0T10, name = MOXduwi, experience = 49, certified = false, content_type = technology2] Technology2 [id = 1T10, name = LpXGRvn, experience = 28, certified = false, content_type = technology2] Technology2 [id = 2T10, name = QeAOjIp, experience = 3, certified = true, content_type = technology2] Technology2 [id = 3T10, name = aVxGhOV , experience = 34, certified = true, content_type = technology2] Technology2 [id = 4T10, name = fbSaBUm, experience = 42, certified = true, content_type = technology2]], content_type = employee2]
He planteado el defecto del código en JIRA: https://issues.apache.org/jira/browse/SOLR-9112