I am inserting POJO's into Solr and now attempting to query and deserialize back into the POJO's. While trying to instantiate the POJO (TwitterStatusModel) it throws an IllegalArgumentException.
It was my understanding that since I am inserting the date into Solr with a String (inserting into a TrieDateField), that I should be able to extract and reinstantiate based on the same datatype, but is Solr looking to set the statusCreatedDate as a java.util.Date? Or a String?
Any help would be much appreciated.
Note: I am formatting the date String (per TrieDateField requirements) properly before inserting into Solr.
Note: When this bug popped up, the two setters (one accepting java.util.Date and the other accepting String) were both named setStatusCreatedDate. I since renamed one to try and narrow down the problem.
Below is my schema:
<?xml version="1.0" encoding="UTF-8" ?>
<schema name="MySolrModel" version="1.5">
<fieldType name="double" class="solr.TrieDoubleField" />
<fieldType name="long" class="solr.TrieLongField" positionIncrementGap="0"/>
<fieldType name="string" class="solr.StrField" sortMissingLast="true" />
<fieldType name="text_en" class="solr.TextField" >
<analyzer type="index">
<tokenizer class="solr.ClassicTokenizerFactory" />
<filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_en.txt"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="date" class="solr.TrieDateField"/>
<fieldType name="int" class="solr.TrieIntField" />
<fieldType name="boolean" class="solr.BoolField" />
<uniqueKey>id</uniqueKey>
<defaultSearchField>statusText</defaultSearchField>
<field name="_version_" type="long" indexed="true" stored="true"/>
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
<field name="statusText" type="text_en" indexed="true" stored="true" required="true" multiValued="false" />
<field name="userName" type="string" indexed="true" stored="true" required="true" multiValued="false" />
<field name="placeCountry" type="string" indexed="true" stored="true" required="false" multiValued="false" />
<field name="statusContributorsList" type="long" indexed="false" stored="true" required="false" multiValued="true" />
<field name="statusCreatedDate" type="date" indexed="true" stored="true" required="true" multiValued="false" />
<dynamicField name="*Lat" type="double" indexed="true" stored="true" required="false" multiValued="false" />
<dynamicField name="*Lon" type="double" indexed="true" stored="true" required="false" multiValued="false" />
<dynamicField name="*Int" type="int" indexed="false" stored="true" required="false" multiValued="false" />
<dynamicField name="*Boolean" type="boolean" indexed="false" stored="true" required="false" multiValued="false" />
<dynamicField name="*Long" type="long" indexed="false" stored="true" required="false" multiValued="false" />
<dynamicField name="*String" type="string" indexed="false" stored="true" required="false" multiValued="false" />
</schema>
Here is what I believe to be the relevant portion of the POJO. As you can see, I had a setter that accepted a String and another that accepted a Date. I have tried commenting them each out just to see if perhaps the one wrong was interfering and no such luck. Also, I inserted the @JsonSetter and @JsonIgnoreProperties annotations after this error came about.
public class TwitterStatusModel {
@Field("statusCreatedDate")
@JsonProperty
private String statusCreatedDate = "";
public String getStatusCreatedDate() {
return this.statusCreatedDate;
}
@JsonSetter
public void setStatusCreatedDate(String statusCreatedDate) {
this.statusCreatedDate = statusCreatedDate;
}
// @JsonIgnoreProperties
// public void setStatusCreatedDateFromDate(Date created) {
// this.statusCreatedDate = (DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.S'Z'")).print(new DateTime(created));
// }
Here is the code that inserts the POJO's into Solr followed by the code extracting them from Solr.
public void insertDocumentList(List<TwitterStatusModel> tweetList) {
try {
server.addBeans(tweetList);
} catch (IOException ioe) {
TwitterCollectionScheduleBean.log.error(ioe);
} catch (SolrServerException sse) {
TwitterCollectionScheduleBean.log.error(sse);
}
}
public void writeRecent() {
SolrQuery query = new SolrQuery();
query.setQuery("*:*");
List<TwitterStatusModel> list = query(query).getBeans(TwitterStatusModel.class);
}
public QueryResponse query(SolrQuery query) {
QueryResponse resp = null;
try {
resp = server.query(query);
} catch (SolrServerException sse) {
TwitterCollectionScheduleBean.log.error(sse);
}
return resp;
}
Finally, below is the exception. I tried to cut it down as much as possible...
01:26:52,995 ERROR [org.jboss.as.ejb3] (ServerService Thread Pool -- 101) javax.ejb.EJBTransactionRolledbackException: Could not instantiate object of class com.mycompany.MyProject.twitter.util.TwitterStatusModel
01:26:52,996 ERROR [org.jboss.as.ejb3.invocation] (ServerService Thread Pool -- 101) JBAS014134: EJB Invocation failed on component JsonSerializer for method public void com.mycompany.MyProject.json.JsonSerializer.writeRecent(): javax.ejb.EJBTransactionRolledbackException: Could not instantiate object of class com.mycompany.MyProject.twitter.util.TwitterStatusModel
at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleInCallerTx(CMTTxInterceptor.java:163) [wildfly-ejb3-8.2.0.Final.jar:8.2.0.Final]
at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:253) [wildfly-ejb3-8.2.0.Final.jar:8.2.0.Final]
at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:342) [wildfly-ejb3-8.2.0.Final.jar:8.2.0.Final]
at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:239) [wildfly-ejb3-8.2.0.Final.jar:8.2.0.Final]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41) [wildfly-ejb3-8.2.0.Final.jar:8.2.0.Final]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.as.ejb3.component.invocationmetrics.WaitTimeInterceptor.processInvocation(WaitTimeInterceptor.java:43) [wildfly-ejb3-8.2.0.Final.jar:8.2.0.Final]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.as.ejb3.security.SecurityContextInterceptor.processInvocation(SecurityContextInterceptor.java:95) [wildfly-ejb3-8.2.0.Final.jar:8.2.0.Final]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.as.ejb3.component.interceptors.ShutDownInterceptorFactory$1.processInvocation(ShutDownInterceptorFactory.java:64) [wildfly-ejb3-8.2.0.Final.jar:8.2.0.Final]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.as.ejb3.component.interceptors.LoggingInterceptor.processInvocation(LoggingInterceptor.java:59) [wildfly-ejb3-8.2.0.Final.jar:8.2.0.Final]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.as.ejb3.component.interceptors.AdditionalSetupInterceptor.processInvocation(AdditionalSetupInterceptor.java:55) [wildfly-ejb3-8.2.0.Final.jar:8.2.0.Final]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.invocation.ContextClassLoaderInterceptor.processInvocation(ContextClassLoaderInterceptor.java:64)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:326)
at org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:448)
at org.jboss.invocation.AccessCheckingInterceptor.processInvocation(AccessCheckingInterceptor.java:61)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:326)
at org.jboss.invocation.PrivilegedWithCombinerInterceptor.processInvocation(PrivilegedWithCombinerInterceptor.java:80)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)
at org.jboss.as.ee.component.ViewService$View.invoke(ViewService.java:185)
at org.jboss.as.ee.component.ViewDescription$1.processInvocation(ViewDescription.java:182)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)
at org.jboss.as.ee.component.ProxyInvocationHandler.invoke(ProxyInvocationHandler.java:73)
at com.mycompany.MyProject.json.JsonSerializer$$$view86.writeRecent(Unknown Source) [classes:]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_75]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_75]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_75]
at java.lang.reflect.Method.invoke(Method.java:606) [rt.jar:1.7.0_75]
at org.jboss.weld.util.reflection.Reflections.invokeAndUnwrap(Reflections.java:414) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
at org.jboss.weld.bean.proxy.EnterpriseBeanProxyMethodHandler.invoke(EnterpriseBeanProxyMethodHandler.java:127) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
at org.jboss.weld.bean.proxy.EnterpriseTargetBeanInstance.invoke(EnterpriseTargetBeanInstance.java:56) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
at org.jboss.weld.bean.proxy.InjectionPointPropagatingEnterpriseTargetBeanInstance.invoke(InjectionPointPropagatingEnterpriseTargetBeanInstance.java:65) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:100) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
at com.mycompany.MyProject.json.JsonSerializer$Proxy$_$$_Weld$EnterpriseProxy$.writeRecent(Unknown Source) [classes:]
at com.mycompany.MyProject.scheduler.TwitterCollectionScheduleBean.init(TwitterCollectionScheduleBean.java:86) [classes:]
Caused by: org.apache.solr.client.solrj.beans.BindingException: Could not instantiate object of class com.mycompany.MyProject.twitter.util.TwitterStatusModel
at org.apache.solr.client.solrj.beans.DocumentObjectBinder.getBean(DocumentObjectBinder.java:68) [solr-solrj-4.10.3.jar:4.10.3 1644336 - mark - 2014-12-10 00:35:46]
at org.apache.solr.client.solrj.beans.DocumentObjectBinder.getBeans(DocumentObjectBinder.java:47) [solr-solrj-4.10.3.jar:4.10.3 1644336 - mark - 2014-12-10 00:35:46]
at org.apache.solr.client.solrj.response.QueryResponse.getBeans(QueryResponse.java:536) [solr-solrj-4.10.3.jar:4.10.3 1644336 - mark - 2014-12-10 00:35:46]
at com.mycompany.MyProject.json.JsonSerializer.writeRecent(JsonSerializer.java:36) [classes:]
Caused by: org.apache.solr.client.solrj.beans.BindingException: Exception while setting value : Tue Feb 17 10:48:39 EST 2015 on private java.lang.String com.mycompany.MyProject.twitter.util.TwitterStatusModel.statusCreatedDate
at org.apache.solr.client.solrj.beans.DocumentObjectBinder$DocField.set(DocumentObjectBinder.java:370) [solr-solrj-4.10.3.jar:4.10.3 1644336 - mark - 2014-12-10 00:35:46]
at org.apache.solr.client.solrj.beans.DocumentObjectBinder$DocField.inject(DocumentObjectBinder.java:353) [solr-solrj-4.10.3.jar:4.10.3 1644336 - mark - 2014-12-10 00:35:46]
at org.apache.solr.client.solrj.beans.DocumentObjectBinder.getBean(DocumentObjectBinder.java:64) [solr-solrj-4.10.3.jar:4.10.3 1644336 - mark - 2014-12-10 00:35:46]
... 140 more
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.String field com.mycompany.MyProject.twitter.util.TwitterStatusModel.statusCreatedDate to java.util.Date
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164) [rt.jar:1.7.0_75]
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168) [rt.jar:1.7.0_75]
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81) [rt.jar:1.7.0_75]
at java.lang.reflect.Field.set(Field.java:741) [rt.jar:1.7.0_75]
at org.apache.solr.client.solrj.beans.DocumentObjectBinder$DocField.set(DocumentObjectBinder.java:364) [solr-solrj-4.10.3.jar:4.10.3 1644336 - mark - 2014-12-10 00:35:46]
... 142 more
01:26:53,011 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 101) MSC000001: Failed to start service jboss.deployment.unit."MyProject-1.0-SNAPSHOT.war".component.TwitterCollectionScheduleBean.START: org.jboss.msc.service.StartException in service jboss.deployment.unit."MyProject-1.0-SNAPSHOT.war".component.TwitterCollectionScheduleBean.START: java.lang.IllegalStateException: JBAS011048: Failed to construct component instance
... 6 more
Caused by: javax.ejb.EJBTransactionRolledbackException: Could not instantiate object of class com.mycompany.MyProject.twitter.util.TwitterStatusModel
at com.mycompany.MyProject.json.JsonSerializer$Proxy$_$$_Weld$EnterpriseProxy$.writeRecent(Unknown Source)
at com.mycompany.MyProject.scheduler.TwitterCollectionScheduleBean.init(TwitterCollectionScheduleBean.java:86)
... 11 more
Caused by: org.apache.solr.client.solrj.beans.BindingException: Could not instantiate object of class com.mycompany.MyProject.twitter.util.TwitterStatusModel
at org.apache.solr.client.solrj.beans.DocumentObjectBinder.getBean(DocumentObjectBinder.java:68)
at org.apache.solr.client.solrj.beans.DocumentObjectBinder.getBeans(DocumentObjectBinder.java:47)
at org.apache.solr.client.solrj.response.QueryResponse.getBeans(QueryResponse.java:536)
at com.mycompany.MyProject.json.JsonSerializer.writeRecent(JsonSerializer.java:36)
... 101 more
Caused by: org.apache.solr.client.solrj.beans.BindingException: Exception while setting value : Tue Feb 17 10:48:39 EST 2015 on private java.lang.String com.mycompany.MyProject.twitter.util.TwitterStatusModel.statusCreatedDate
at org.apache.solr.client.solrj.beans.DocumentObjectBinder$DocField.set(DocumentObjectBinder.java:370)
at org.apache.solr.client.solrj.beans.DocumentObjectBinder$DocField.inject(DocumentObjectBinder.java:353)
at org.apache.solr.client.solrj.beans.DocumentObjectBinder.getBean(DocumentObjectBinder.java:64)
... 140 more
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.String field com.mycompany.MyProject.twitter.util.TwitterStatusModel.statusCreatedDate to java.util.Date
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164) [rt.jar:1.7.0_75]
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168) [rt.jar:1.7.0_75]
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81) [rt.jar:1.7.0_75]
at java.lang.reflect.Field.set(Field.java:741) [rt.jar:1.7.0_75]
at org.apache.solr.client.solrj.beans.DocumentObjectBinder$DocField.set(DocumentObjectBinder.java:364)
... 142 more
01:26:53,029 ERROR [org.jboss.as.controller.management-operation] (DeploymentScanner-threads - 2) JBAS014613: Operation ("full-replace-deployment") failed - address: ([]) - failure description: {"JBAS014671: Failed services" => {"jboss.deployment.unit.\"MyProject-1.0-SNAPSHOT.war\".component.TwitterCollectionScheduleBean.START" => "org.jboss.msc.service.StartException in service jboss.deployment.unit.\"MyProject-1.0-SNAPSHOT.war\".component.TwitterCollectionScheduleBean.START: java.lang.IllegalStateException: JBAS011048: Failed to construct component instance
Caused by: java.lang.IllegalStateException: JBAS011048: Failed to construct component instance
Caused by: javax.ejb.EJBTransactionRolledbackException: Could not instantiate object of class com.mycompany.MyProject.twitter.util.TwitterStatusModel
Caused by: org.apache.solr.client.solrj.beans.BindingException: Could not instantiate object of class com.mycompany.MyProject.twitter.util.TwitterStatusModel
Caused by: org.apache.solr.client.solrj.beans.BindingException: Exception while setting value : Tue Feb 17 10:48:39 EST 2015 on private java.lang.String com.mycompany.MyProject.twitter.util.TwitterStatusModel.statusCreatedDate
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.String field com.mycompany.MyProject.twitter.util.TwitterStatusModel.statusCreatedDate to java.util.Date"}}
It seems that even though I kept the typecast at the setter method:
public void setStatusCreatedDateFromDate(Date created) {
this.statusCreatedDate = (DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.S'Z'")).print(new DateTime(created));
}
Solr doesn't look at the type it can provide, it looks at the type of the POJO's field. I wouldn't think Solr would care what type the actual field is so long as it gets and can set using the correct type, however it does. Solr wants the FIELD to be of the correct type. Below is the solution:
@Field("statusCreatedDate")
@JsonProperty
private Date statusCreatedDate = new Date();
public void setStatusCreatedDate(Date created) {
this.statusCreatedDate = created;
}
I don't know if there is a work-around, however the fix is to simply change the POJO. Interestingly enough, there are records that were indexed where the statusCreatedDate was in String format and others in long format, forcing me to dump and refactor the data, correct the POJO (using the java.util.Date class) and start over.
As an aside, I found that while Solr would allow insertion of a POJO long type into Solr's String type, it would not deserialize back to the POJO (String --> long).
For anyone who reads this, ensure that the types in your POJO line up exactly with the schema.xml types.