Apache Solr – How to start Spring Data Solr with SpringBoot

Solr powers the search with highly reliable, centralized configuration, scalablility and more for heavily-trafficked websites and applications. So in the tutorial, JavaSampleApproach will show how to create a Spring Data Solr application with SpringBoot.

Related posts:
How to start SpringBoot ElasticSearch using Spring Data

I. Technology

– Java 1.8
– Maven 3.3.9
– Spring Tool Suite – Version 3.8.1.RELEASE
– Spring Boot: 1.5.6RELEASE
– Solr 6.6.0

II. SpringBoot & Solr

spring data solr - springboot - architecture

SpringBoot provides spring-boot-starter-data-solr Starter to support connecting and abstractions on top of Spring Data Solr.

1. Solr connection

In application.properties file, We use spring.data.solr.* to configure Solr connection.
Here is the details of sourcecode – SolrProperties:


@ConfigurationProperties(prefix = "spring.data.solr")
public class SolrProperties {

	/**
	 * Solr host. Ignored if "zk-host" is set.
	 */
	private String host = "http://127.0.0.1:8983/solr";

	/**
	 * ZooKeeper host address in the form HOST:PORT.
	 */
	private String zkHost;
	
	...

}

By default the instance will attempt to connect to a server using http://localhost:8983/solr. And we can add @Bean with SolrClient type to override it.

2. Spring Data Solr repositories

We use @SolrDocument to create Solr document:


@SolrDocument(solrCoreName = "customer")
public class Customer {
	@Id
	@Field
	private String id;

	@Field
	private String name;
	
	@Field
	private Integer age;
	
	public Customer() {
	}
	
	...

Using SolrCrudRepository to create Solr repositories:


...

import org.springframework.data.solr.repository.SolrCrudRepository;

import com.javasampleapproach.solr.model.Customer;

public interface CustomerRepository extends SolrCrudRepository {
	List findByNameEndsWith(String name);
}

Details about interface SolrCrudRepository:

public interface SolrCrudRepository<T, ID extends Serializable> extends SolrRepository<T, ID>,
		PagingAndSortingRepository<T, ID> {
}

III. Practice

In the tutorial, we create a Spring Data Solr project with SpringBoot:

spring data solr - springboot - project structure

Step to do:
– Create SpringBoot project
– Create Solr document model
– Create Solr repository
– Run and check results

1. Create SpringBoot project

Using Spring Tool Suite, create a SpringBoot project. Then open pom.xml file, add spring-data-solr dependency:


...
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>

...

2. Create Solr document model

Using @SolrDocument annotation, create a Solr document model:


package com.javasampleapproach.solr.model;

import org.apache.solr.client.solrj.beans.Field;
import org.springframework.data.annotation.Id;
import org.springframework.data.solr.core.mapping.SolrDocument;

@SolrDocument(solrCoreName = "customer")
public class Customer {
	@Id
	@Field
	private String id;

	@Field
	private String name;
	
	@Field
	private Integer age;
	
	public Customer() {
	}
	
	public Customer(String id, String name, Integer age){
		this.id = id;
		this.name = name;
		this.age = age;
	}
	
	public void setId(String id){
		this.id = id;
	}
	
	public String getId(){
		return this.id;
	}
	
	public void setName(String name){
		this.name = name;
	}
	
	public String getName(){
		return this.name;
	}
	
	public void setAge(Integer age){
		this.age = age;
	}
	
	public Integer getAge(){
		return this.age;
	}
	
	@Override
	public String toString() {
		return "Customer [id=" + this.id + ", name=" + this.name + ", age=" + this.age + "]";
	}
}

3. Create Solr repository

Using interface SolrCrudRepository to create a CustomerRepository:


package com.javasampleapproach.solr.repo;

import java.util.List;

import org.springframework.data.solr.repository.SolrCrudRepository;

import com.javasampleapproach.solr.model.Customer;

public interface CustomerRepository extends SolrCrudRepository {
	List findByNameEndsWith(String name);
}

findByNameEndsWith is used to fetch all Customer documents that have name ending with specified argument.

Open application.properties file, configure solr.host:


spring.data.solr.host=http://localhost:8983/solr

4. Run and check results

4.1 Start Solr engine

Start Solr by commandline: solr-6.6.0\bin>solr start

spring data solr - springboot - start solr

spring data solr - springboot - admin at start time

Create a Solr core customer by commandline: solr create -c customer

spring data solr - springboot - create core

spring data solr - springboot - admin has customer core

4.2 Run SpringData Solr application

Build and Run the SpringBoot project with commandlines: {mvn clean install, mvn spring-boot:run}.

Logs:


--------------------------------
Select all Customers:
--------------------------------
Customer [id=1, name=Jack, age=20]
Customer [id=2, name=Adam, age=24]
Customer [id=3, name=Kim, age=27]
Customer [id=4, name=David, age=30]
Customer [id=5, name=Peter, age=21]
--------------------------------
Find Customers that have names EndsWith m:
--------------------------------
Customer [id=2, name=Adam, age=24]
Customer [id=3, name=Kim, age=27]

spring data solr - springboot - admin excute select query

More practice:
– Delete Solr core customer by commandline: solr delete -c customer

spring data solr - springboot - delete core

– Stop Apache Solr by commandline: solr stop -p 8983

spring data solr - springboot - stop solr

IV. Sourcecode

SpringBootApacheSolr

5 thoughts on “Apache Solr – How to start Spring Data Solr with SpringBoot”

  1. Hello,

    Thanks for your tutorial. I am getting below error while running Spring boot application.

    java.lang.IllegalStateException: Failed to execute CommandLineRunner
    	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:735) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
    	at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:716) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
    	at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:703) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
    	at org.springframework.boot.SpringApplication.run(SpringApplication.java:304) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
    	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
    	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
    	at com.example.solr.SpringBootSolrApplication.main(SpringBootSolrApplication.java:25) [classes/:na]
    Caused by: org.springframework.data.solr.UncategorizedSolrException: Error from server at http://localhost:8983/solr/customer: Expected mime type application/octet-stream but got text/html. 
    
    
    Error 404 Not Found
    
    HTTP ERROR 404
    Problem accessing /solr/customer/customer/update. Reason:
    
        Not Found

    ; nested exception is org.apache.solr.client.solrj.impl.HttpSolrClient$RemoteSolrException: Error from server at http://localhost:8983/solr/customer: Expected mime type application/octet-stream but got text/html.

    Error 404 Not Found

    HTTP ERROR 404
    Problem accessing /solr/customer/customer/update. Reason:

        Not Found

    at org.springframework.data.solr.core.SolrTemplate.execute(SolrTemplate.java:224) ~[spring-data-solr-2.1.8.RELEASE.jar:na]
    at org.springframework.data.solr.core.SolrTemplate.saveBeans(SolrTemplate.java:376) ~[spring-data-solr-2.1.8.RELEASE.jar:na]
    at org.springframework.data.solr.core.SolrTemplate.saveBeans(SolrTemplate.java:365) ~[spring-data-solr-2.1.8.RELEASE.jar:na]
    at org.springframework.data.solr.core.SolrTemplate.saveBeans(SolrTemplate.java:347) ~[spring-data-solr-2.1.8.RELEASE.jar:na]
    at org.springframework.data.solr.repository.support.SimpleSolrRepository.save(SimpleSolrRepository.java:163) ~[spring-data-solr-2.1.8.RELEASE.jar:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_151]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_151]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_151]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_151]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:504) ~[spring-data-commons-1.13.8.RELEASE.jar:na]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:489) ~[spring-data-commons-1.13.8.RELEASE.jar:na]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:461) ~[spring-data-commons-1.13.8.RELEASE.jar:na]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56) ~[spring-data-commons-1.13.8.RELEASE.jar:na]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) ~[spring-tx-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282) ~[spring-tx-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57) ~[spring-data-commons-1.13.8.RELEASE.jar:na]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at com.sun.proxy.$Proxy42.save(Unknown Source) ~[na:na]
    at com.example.solr.SolrConfig.run(SolrConfig.java:44) ~[classes/:na]
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:732) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
    ... 6 common frames omitted
    Caused by: org.apache.solr.client.solrj.impl.HttpSolrClient$RemoteSolrException: Error from server at http://localhost:8983/solr/customer: Expected mime type application/octet-stream but got text/html.

    Error 404 Not Found

    HTTP ERROR 404
    Problem accessing /solr/customer/customer/update. Reason:

        Not Found
    1. Hello Kumar,

      We had double check, everthing works wells!
      Please do the right steps in tutorial:

      – Start Solr by commandline: solr-6.6.0\bin>solr start
      – Then create a Solr core customer by commandline: solr create -c customer

      Then run SpringData Solr application

      I see your problems is:

      Caused by: org.springframework.data.solr.UncategorizedSolrException: Error from server at http://localhost:8983/solr/customer: Expected mime type application/octet-stream but got text/html.
      
      Error 404 Not Found
      
      HTTP ERROR 404
      Problem accessing /solr/customer/customer/update. Reason:
      
          Not Found
      ; nested exception is org.apache.solr.client.solrj.impl.HttpSolrClient$RemoteSolrException: Error from server at http://localhost:8983/solr/customer: Expected mime type application/octet-stream but got text/html.
      
      Error 404 Not Found
      
      HTTP ERROR 404
      Problem accessing /solr/customer/customer/update. Reason:
      
          Not Found
      

      -> mean your forgot creating Solr core customer.

      Regards,
      JSA

Leave a Reply

Your email address will not be published. Required fields are marked *