spring-data-solr2.1.3+solr6.5.1 NoSuchMethodError: org.apache.solr.common.SolrInputDocument: method <init>()V not found

spring-data-solr2.1.3+solr6.5.1 NoSuchMethodError: org.apache.solr.common.SolrInputDocument: method <init>()V not found

我用的是spring-data-solr(2.1.3)和solr(6.5.1),但是当我用solrTemplate.saveBean(Command)的时候,抛出异常:

java.lang.NoSuchMethodError: org.apache.solr.common.SolrInputDocument: method ()V not found

这是我的pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.catcher92.demo</groupId>
    <artifactId>solr</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>${artifactId}</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
        <maven.compiler.plugin.version>2.3.2</maven.compiler.plugin.version>
        <solr.version>6.5.1</solr.version>
        <spring.data.solr.version>2.1.3.RELEASE</spring.data.solr.version>
        <fastjson.version>1.2.32</fastjson.version>
        <junit.version>4.12</junit.version>
        <spring.version>4.3.8.RELEASE</spring.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.apache.solr</groupId>
                <artifactId>solr-solrj</artifactId>
                <version>${solr.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework.data</groupId>
                <artifactId>spring-data-solr</artifactId>
                <version>${spring.data.solr.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.version}</version>
            </dependency>

            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.apache.solr</groupId>
            <artifactId>solr-solrj</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-solr</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin.version}</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

这是我的实体

package com.catcher92.demo.solr.bean;

import org.apache.solr.client.solrj.beans.Field;
import java.io.Serializable;
import java.util.List;

/**
 * Created by catcher92 on 2017/6/7.
 */
public class Command implements Serializable{

    @Field
    private String id;
    @Field
    private String command;
    @Field
    private String description;
    @Field
    private List<String> contents;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getCommand() {
        return command;
    }

    public void setCommand(String command) {
        this.command = command;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public List<String> getContents() {
        return contents;
    }

    public void setContents(List<String> contents) {
        this.contents = contents;
    }

    @Override
    public String toString() {
        return "Command{" +
                "id=" + id +
                ", command='" + command + '\'' +
                ", description='" + description + '\'' +
                ", contents=" + contents +
                '}';
    }
}

这是我的 solr 配置

package com.catcher92.demo.solr.spring.config;

import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.repository.config.EnableSolrRepositories;

import javax.annotation.Resource;

/**
* Created by catcher92 on 2017/6/7.
*/
@Configuration
@EnableSolrRepositories()
@PropertySource("classpath:solr.properties")
public class SolrConfig {
    static final String SOLR_HOST = "solr.host";

    @Resource
    private Environment environment;

    @Bean
    public HttpSolrClient solrClient() {
        String solrHost = environment.getRequiredProperty(SOLR_HOST);
        return new HttpSolrClient.Builder(solrHost).build();
    }

    @Bean
    public SolrTemplate solrTemplate() {
        return new SolrTemplate(solrClient());
    }
}

这是我的测试代码

package com.catcher92.demo;

import com.catcher92.demo.solr.bean.Command;
import com.catcher92.demo.solr.spring.config.SpringConfig;
import org.apache.solr.common.SolrInputDocument;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.Arrays;

/**
* Created by catcher92 on 2017/6/7.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfig.class})
public class SpringDataSolrTest {

    @Autowired
    private SolrTemplate solrTemplate;


    @Test
    public void testAdd() {
        Command command = new Command();
        command.setId("110");
        command.setCommand("template测试精彩");
        command.setDescription("spring data solr template测试精彩描述");
        command.setContents(Arrays.asList("测试精彩1", "2精彩测试"));
        solrTemplate.saveBean(command);
        solrTemplate.commit();
    }

    @Test
    public void testDel() {
        solrTemplate.deleteById("110");
        solrTemplate.commit();
    }
}

当我测试方法 testAdd() 时,错误消息如下:

java.lang.NoSuchMethodError: org.apache.solr.common.SolrInputDocument: method <init>()V not found

    at org.springframework.data.solr.core.SolrTemplate.convertBeanToSolrInputDocument(SolrTemplate.java:1131)
    at org.springframework.data.solr.core.SolrTemplate.doInSolr(SolrTemplate.java:335)
    at org.springframework.data.solr.core.SolrTemplate.doInSolr(SolrTemplate.java:330)
    at org.springframework.data.solr.core.SolrTemplate.execute(SolrTemplate.java:220)
    at org.springframework.data.solr.core.SolrTemplate.saveBean(SolrTemplate.java:330)
    at org.springframework.data.solr.core.SolrTemplate.saveBean(SolrTemplate.java:318)
    at org.springframework.data.solr.core.SolrTemplate.saveBean(SolrTemplate.java:300)
    at com.catcher92.demo.SpringDataSolrTest.testAdd(SpringDataSolrTest.java:39)

我遇到了同样的问题。这是因为在 Sorj 6.x 中没有 SolrInputDocument() 参数的默认构造函数被删除了。在我的例子中,我使用了一个解决方法:将我的实体转换为 SolrInputDocument 然后调用 saveBean() 方法。

spring-data-solrsolr-solrj有这样的兼容性table:

 spring-data-solr | solr-solrj
 -----------------------------
      2.1.15      | 5.5.0
      3.0.10      | 6.5.0
       4.0.0      | 7.4.0

因此必须使用两个 jar 的相应版本。

例如使用 maven:

    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-solr</artifactId>
        <version>4.0.0.RELEASE</version>
    </dependency>


    <dependency>
        <groupId>org.apache.solr</groupId>
        <artifactId>solr-solrj</artifactId>
        <version>7.4.0</version>
    </dependency>