对 bean 的 Solr 查询 - java.lang.IllegalArgumentException

Solr query to beans - java.lang.IllegalArgumentException

我正在将 POJO 插入 Solr,现在正尝试查询并反序列化回 POJO。在尝试实例化 POJO (TwitterStatusModel) 时它抛出 IllegalArgumentException。

据我了解,由于我使用字符串将日期插入 Solr(插入到 TrieDateField 中),因此我应该能够基于相同的数据类型提取和重新实例化,但 Solr 是否希望设置statusCreatedDate 作为 java.util.Date?还是字符串?

如有任何帮助,我们将不胜感激。

注意:在插入 Solr 之前,我正在正确格式化日期字符串(根据 TrieDateField 要求)。

注意:弹出此错误时,两个 setter(一个接受 java.util.Date,另一个接受 String)都被命名为 setStatusCreatedDate。我后来重命名了一个以尝试缩小问题范围。

下面是我的架构:

<?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>

我认为这是 POJO 的相关部分。如您所见,我有一个 setter 接受字符串,另一个接受日期。我试过对它们一一进行评论,只是想看看是否有一个错误是在干扰,而没有这样的运气。此外,我在出现此错误后插入了@JsonSetter 和@JsonIgnoreProperties 注释。

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));
//    }

这是将 POJO 插入 Solr 的代码,然后是从 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;
}

最后,下面是例外。我尽量减少它...

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.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.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"}}

似乎即使我在 setter 方法中保留了类型转换:

public void setStatusCreatedDateFromDate(Date created) {
    this.statusCreatedDate = (DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.S'Z'")).print(new DateTime(created));
}

Solr 不看它能提供的类型,它看POJO 的字段的类型。我不认为 Solr 会关心实际字段是什么类型,只要它获取并可以使用正确的类型进行设置,但它确实如此。 Solr 希望 FIELD 是正确的类型。以下是解决方案:

@Field("statusCreatedDate")
@JsonProperty
private Date statusCreatedDate = new Date();

public void setStatusCreatedDate(Date created) {
    this.statusCreatedDate = created;
}

我不知道是否有解决方法,但解决方法是简单地更改 POJO。有趣的是,有些记录被索引,其中 statusCreatedDate 为字符串格式,其他记录为长格式,迫使我转储和重构数据,更正 POJO(使用 java.util.Date class)并开始结束了

顺便说一句,我发现虽然 Solr 允许将 POJO long 类型插入到 Solr 的 String 类型中,但它不会反序列化回 POJO (String --> long)。

对于阅读本文的任何人,请确保您的 POJO 中的类型与 schema.xml 类型完全一致。