Spring Data Solr

Spring Data Solr CRUD Application Spring Boot

In this article, I will discuss an example of the Spring Data Solr CRUD Application using Spring Boot. I have already discussed the Spring Data Solr such how to install Apache Solr and how to configure the Spring Data Solr to your spring application.

Spring Data provides an easy and very generic way to create the repositories for each technology such as Solr, Cassandra, MongoDB, JPA etc. In Spring Data Solr tutorial, I have discussed how to create Spring Data Solr repositories using Spring Data interface or custom repository creation without using Spring Data repository interface. Also, we have learned to create dynamic Solr queries and sorting the Solr query results. And how to render this Solr query result with pagination.

Let’s create an application with CRUD operation using Spring Data Solr and Spring Boot.

Spring Data Solr CRUD Application

As we know that the Apache Solr is an open source ready to deploy enterprise full-text search engine. But in this article, I will show you how to do a simple Solr configuration and how to interact with the Solr server. Let’s first start the Solr server as we have configured in the previous articles as the following diagram:

As you can see in the above diagram, the Solr server is started now and running at the 8983 port. You can see the running Solr by launching the Solr Admin UI in your web browser: http://localhost:8983/solr/ as the following:

You can see the above diagram of the Solr server admin dashboard. Finally, you can create the collections in the Solr server. And we will use these collections into our application for CRUD operations. Let’s create collections by using the following command.

bin\solr create -c Order

After creating the Order collection, let’s move to index this collection with Data using application.

Adding Spring Data to application

Spring team has created Spring Data projects to simplify DAO layer implementation and removing boilerplate codes. Like other Spring Data project. Spring Data Solr is also created for removing boilerplate codes and simplifying DAO implementation in the spring application. Let’s see how to add Spring Data Solr in your application by using the following Maven and Gradle dependency.

Maven Dependency
Let’s start by adding the Spring Data Solr dependency on our pom.xml:

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

Gradle Dependency
Let’s start by adding the Spring Data Solr dependency on our build.gradle:

  
{
compile group: 'org.springframework.data', name: 'spring-data-solr', version: '3.0.10.RELEASE'
}

You can configure the latest dependency of the Spring Data Solr project in your application. Next, let’s define a document class for the Order collection in this application.

Defining the Document Class

In this application, we are using Order collection, so, let’s define a document called Order as the following class:

  
package com.doj.app.pojo;

import org.springframework.data.annotation.Id;
import org.springframework.data.solr.core.mapping.Indexed;
import org.springframework.data.solr.core.mapping.SolrDocument;

/**
* @author Dinesh.Rajput
*
*/
@SolrDocument(collection="Order")
public class Order {

@Id
@Indexed(name = "oid", type = "long")
private Long orderid;

@Indexed(name = "oname", type = "string")
private String orderName;

@Indexed(name = "odesc", type = "string")
private String orderDescription;

@Indexed(name = "pname", type = "string")
private String productName;

@Indexed(name = "cname", type = "string")
private String customerName;

@Indexed(name = "cmobile", type = "string")
private String customerMobile;

public Long getOrderid() {
return orderid;
}

public void setOrderid(Long orderid) {
this.orderid = orderid;
}

public String getOrderName() {
return orderName;
}

public void setOrderName(String orderName) {
this.orderName = orderName;
}

public String getProductName() {
return productName;
}

public void setProductName(String productName) {
this.productName = productName;
}

public String getCustomerName() {
return customerName;
}

public void setCustomerName(String customerName) {
this.customerName = customerName;
}

public String getCustomerMobile() {
return customerMobile;
}

public void setCustomerMobile(String customerMobile) {
this.customerMobile = customerMobile;
}

public String getOrderDescription() {
return orderDescription;
}

public void setOrderDescription(String orderDescription) {
this.orderDescription = orderDescription;
}

}

In the above document class, we have annotated this class @SolrDocument annotation. This annotation indicates that the Order class is a Solr document and indexed to collection name Order. In this class, you would notice, the fields are annotated with @Indexed. It indicates these fields will be indexed to the Order collection and will be searchable. Also, a field of the Order class “orderid” is annotated with @Id annotation. This means that the field “orderid” is like primary key of this a Solr document.

In the next section, I will define the Spring Data Solr repository interface for this application.

Defining Repository Interface

Let’s create a repository interface for the Order Solr collection and this interface extending a repository provided by Spring Data Solr. As the given class below:

package com.doj.app.repository;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.solr.repository.Query;
import org.springframework.data.solr.repository.SolrCrudRepository;

import com.doj.app.pojo.Order;

/**
* @author Dinesh.Rajput
*
*/
public interface SolrOrderRepository extends SolrCrudRepository<Order, Long> {

Order findByOrderid(Long orderid);

@Query("odesc:*?0*")
Page<Order> findByOrderDescription(String searchTerm, Pageable pageable);

@Query("odesc:*?0* OR oname:*?0* OR pname:*?0*")
Page<Order> findByCustomerQuery(String searchTerm, Pageable pageable);

}

The above repository interface, we have naturally parametrized this with Order and Long as our entity id. As we know that this is Spring Boot application, so we don’t need to configure Spring Data Solr manually for the Spring Boot application. The Spring Boot application will automatically configure the required configuration by default according to the library available on the classpath of the application. But we have to provide Apache Solr server address by configuring it with the application.properties file as the following:

Application configuration file

First, let’s see the configuration file for the Spring Boot application.
application.properties

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

Let’s assume, if you don’t want to use default configuration of the Spring Boot application or you are not using the Spring Boot for this application then you have to explicitly configure the Spring Data Solr into this Spring Data Solr CRUD Application.

Explicitly Java Based Configuration

Let’s see the following Java-based configuration for the Spring Data Solr in the Spring Data Solr CRUD Application.

/**
 * 
 */
package com.doj.app.config;

import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.repository.config.EnableSolrRepositories;

/**
 * @author Dinesh.Rajput
 *
 */
@Configuration
@EnableSolrRepositories(
		basePackages = "com.doj.app.repository")
@ComponentScan
public class SolrConfig {
	
    @Value("spring.data.solr.host") String solrURL;
	
    @Bean
    public SolrClient solrClient() {
        return new HttpSolrClient.Builder(solrURL).build();
    }
 
    @Bean
    public SolrTemplate solrTemplate(SolrClient client) throws Exception {
        return new SolrTemplate(client);
    }
}

We are using @EnableSolrRepositories to scan the packages for repositories.

Note: If multi-core is not enabled, then by default Spring Data will assume that Solr configuration is for a single core.

Now, move to perform CRUD operation for this Solr collection in the Spring Data Solr CRUD Application.

Indexing, Updating, Deleting, and Querying

In order to search documents in Solr, documents should be indexed to Solr repository. Let’s create a controller class which takes request parameters and index to the Solr document Order.

package com.doj.app.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.doj.app.pojo.Order;
import com.doj.app.repository.SolrOrderRepository;

/**
* @author Dinesh.Rajput
*
*/
@RestController
public class OrderController {

@Autowired
SolrOrderRepository solrOrderRepository;

@PostMapping("/order")
public String createOrder(@RequestBody Order order){
String description = "Order Created";
solrOrderRepository.save(order);
return description;
}

@GetMapping("/order/{orderid}")
public Order readOrder(@PathVariable Long orderid){
return solrOrderRepository.findByOrderid(orderid);
}

@PutMapping("/order")
public String updateOrder(@RequestBody Order order){
String description = "Order Updated";
solrOrderRepository.save(order);
return description;
}

@DeleteMapping("/order/{orderid}")
public String deleteOrder(@PathVariable Long orderid){
String description = "Order Deleted";
solrOrderRepository.delete(solrOrderRepository.findByOrderid(orderid));
return description;
}

@GetMapping("/order/desc/{orderDesc}/{page}")
public List<Order> findOrder(@PathVariable String orderDesc, @PathVariable int page){
return solrOrderRepository.findByOrderDescription(orderDesc, PageRequest.of(page, 2)).getContent();
}

@GetMapping("/order/search/{searchTerm}/{page}")
public List<Order> findOrderBySearchTerm(@PathVariable String searchTerm, @PathVariable int page){
return solrOrderRepository.findByCustomerQuery(searchTerm, PageRequest.of(page, 2)).getContent();
}
}

Create

In the above controller class, we have created all CRUD operation and provided handler methods for these operations. Let’s run this application and index some data by using createOrder() request handler method with /order POST endpoint.

Read

In the above controller class, we have created readOrder() request handler method with /order/{orderid} GET endpoint to read the data from the Solr server using the Spring Data Solr.

Update

In the above controller class, we have created updateOrder() request handler method with /order PUT endpoint to update a given order value.

Delete

In the above controller class, we have created deleteOrder() request handler method with /order/{orderid} DELETE endpoint to delete a document from the Solr collection.

Let’s see the following the Solr dashboard after creating data into Order collection.

 

Summary

This article has all about the Spring Data Solr with Spring Boot and the Apache Solr. It is a quick and practical introduction to Spring Data Solr, covering the basic configuration, defining repositories and perform CRUD operation. In this Spring Data Solr CRUD Application, we have created an application and this application available as a sample project on Github.

 

 

Previous
Dinesh Rajput

Dinesh Rajput is the chief editor of a website Dineshonjava, a technical blog dedicated to the Spring and Java technologies. It has a series of articles related to Java technologies. Dinesh has been a Spring enthusiast since 2008 and is a Pivotal Certified Spring Professional, an author of a book Spring 5 Design Pattern, and a blogger. He has more than 10 years of experience with different aspects of Spring and Java design and development. His core expertise lies in the latest version of Spring Framework, Spring Boot, Spring Security, creating REST APIs, Microservice Architecture, Reactive Pattern, Spring AOP, Design Patterns, Struts, Hibernate, Web Services, Spring Batch, Cassandra, MongoDB, and Web Application Design and Architecture. He is currently working as a technology manager at a leading product and web development company. He worked as a developer and tech lead at the Bennett, Coleman & Co. Ltd and was the first developer in his previous company, Paytm. Dinesh is passionate about the latest Java technologies and loves to write technical blogs related to it. He is a very active member of the Java and Spring community on different forums. When it comes to the Spring Framework and Java, Dinesh tops the list!

Share
Published by
Dinesh Rajput

Recent Posts

Strategy Design Patterns using Lambda

Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…

2 years ago

Decorator Pattern using Lambda

Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…

2 years ago

Delegating pattern using lambda

Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…

2 years ago

Spring Vs Django- Know The Difference Between The Two

Technology has emerged a lot in the last decade, and now we have artificial intelligence;…

2 years ago

TOP 20 MongoDB INTERVIEW QUESTIONS 2022

Managing a database is becoming increasingly complex now due to the vast amount of data…

2 years ago

Scheduler @Scheduled Annotation Spring Boot

Overview In this article, we will explore Spring Scheduler how we could use it by…

2 years ago