diff --git a/pom.xml b/pom.xml
index 857922310f..bd626b3ad0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -95,6 +95,7 @@
spring-data-neo4j
spring-data-redis
spring-data-rest
+ spring-data-solr
spring-dispatcher-servlet
spring-exceptions
spring-freemarker
diff --git a/spring-data-solr/pom.xml b/spring-data-solr/pom.xml
new file mode 100644
index 0000000000..bd48a53d06
--- /dev/null
+++ b/spring-data-solr/pom.xml
@@ -0,0 +1,69 @@
+
+
+ 4.0.0
+ com.baeldung
+ spring-data-solr
+ 0.0.1-SNAPSHOT
+ jar
+ spring-data-solr
+
+
+
+ UTF-8
+ 4.2.5.RELEASE
+ 2.19.1
+ 2.0.4.RELEASE
+
+
+
+
+ org.springframework
+ spring-core
+ ${spring.version}
+
+
+ org.springframework.data
+ spring-data-solr
+ ${spring-data-solr}
+
+
+ org.springframework
+ spring-context
+ ${spring.version}
+
+
+ log4j
+ log4j
+ 1.2.16
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ org.springframework
+ spring-test
+ ${spring.version}
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+
+ **/*IntegrationTest.java
+
+
+
+
+
+
+
diff --git a/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/config/SolrConfig.java b/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/config/SolrConfig.java
new file mode 100644
index 0000000000..1fe1e5468b
--- /dev/null
+++ b/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/config/SolrConfig.java
@@ -0,0 +1,25 @@
+package com.baeldung.spring.data.solr.config;
+
+import org.apache.solr.client.solrj.SolrClient;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
+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;
+
+@Configuration
+@EnableSolrRepositories(basePackages = "com.baeldung.spring.data.solr.repository", namedQueriesLocation = "classpath:solr-named-queries.properties", multicoreSupport = true)
+@ComponentScan
+public class SolrConfig {
+
+ @Bean
+ public SolrClient solrClient() {
+ return new HttpSolrClient("http://localhost:8983/solr");
+ }
+
+ @Bean
+ public SolrTemplate solrTemplate(SolrClient client) throws Exception {
+ return new SolrTemplate(client);
+ }
+}
diff --git a/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/model/Product.java b/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/model/Product.java
new file mode 100644
index 0000000000..7cd0890718
--- /dev/null
+++ b/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/model/Product.java
@@ -0,0 +1,55 @@
+package com.baeldung.spring.data.solr.model;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.solr.core.mapping.Indexed;
+import org.springframework.data.solr.core.mapping.SolrDocument;
+
+@SolrDocument(solrCoreName = "product")
+public class Product {
+
+ @Id
+ @Indexed(name = "id", type = "string")
+ private String id;
+
+ @Indexed(name = "name", type = "string")
+ private String name;
+
+ @Indexed(name = "category", type = "string")
+ private String category;
+
+ @Indexed(name = "description", type = "string")
+ private String description;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getCategory() {
+ return category;
+ }
+
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+}
diff --git a/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/repository/ProductRepository.java b/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/repository/ProductRepository.java
new file mode 100644
index 0000000000..01ec1fb909
--- /dev/null
+++ b/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/repository/ProductRepository.java
@@ -0,0 +1,22 @@
+package com.baeldung.spring.data.solr.repository;
+
+import java.util.List;
+
+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.baeldung.spring.data.solr.model.Product;
+
+public interface ProductRepository extends SolrCrudRepository {
+
+ public List findByName(String name);
+
+ @Query("name:*?0* OR category:*?0* OR description:*?0*")
+ public Page findByCustomQuery(String searchTerm, Pageable pageable);
+
+ @Query(name = "Product.findByNamedQuery")
+ public Page findByNamedQuery(String searchTerm, Pageable pageable);
+
+}
diff --git a/spring-data-solr/src/main/resources/solr-named-queries.properties b/spring-data-solr/src/main/resources/solr-named-queries.properties
new file mode 100644
index 0000000000..cec59cbebd
--- /dev/null
+++ b/spring-data-solr/src/main/resources/solr-named-queries.properties
@@ -0,0 +1 @@
+Product.findByNamedQuery=name:*?0* OR category:*?0* OR description:*?0*
\ No newline at end of file
diff --git a/spring-data-solr/src/test/java/com/baeldung/spring/data/solr/repo/ProductRepositoryIntegrationTest.java b/spring-data-solr/src/test/java/com/baeldung/spring/data/solr/repo/ProductRepositoryIntegrationTest.java
new file mode 100644
index 0000000000..74d94ef91c
--- /dev/null
+++ b/spring-data-solr/src/test/java/com/baeldung/spring/data/solr/repo/ProductRepositoryIntegrationTest.java
@@ -0,0 +1,144 @@
+package com.baeldung.spring.data.solr.repo;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.baeldung.spring.data.solr.config.SolrConfig;
+import com.baeldung.spring.data.solr.model.Product;
+import com.baeldung.spring.data.solr.repository.ProductRepository;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = SolrConfig.class)
+public class ProductRepositoryIntegrationTest {
+
+ @Autowired
+ private ProductRepository productRepository;
+
+ @Before
+ public void clearSolrData() {
+ productRepository.deleteAll();
+ }
+
+ @Test
+ public void whenSavingProduct_thenAvailableOnRetrieval() throws Exception {
+ final Product product = new Product();
+ product.setId("P000089998");
+ product.setName("Desk");
+ product.setCategory("Furniture");
+ product.setDescription("New Desk");
+ productRepository.save(product);
+ final Product retrievedProduct = productRepository.findOne(product.getId());
+ assertEquals(product.getId(), retrievedProduct.getId());
+ }
+
+ @Test
+ public void whenUpdatingProduct_thenChangeAvailableOnRetrieval() throws Exception {
+ final Product product = new Product();
+ product.setId("P0001");
+ product.setName("T-Shirt");
+ product.setCategory("Kitchen");
+ product.setDescription("New T-Shirt");
+ productRepository.save(product);
+
+ product.setCategory("Clothes");
+ productRepository.save(product);
+
+ final Product retrievedProduct = productRepository.findOne(product.getId());
+ assertEquals(product.getCategory(), retrievedProduct.getCategory());
+ }
+
+ @Test
+ public void whenDeletingProduct_thenNotAvailableOnRetrieval() throws Exception {
+ final Product product = new Product();
+ product.setId("P0001");
+ product.setName("Desk");
+ product.setCategory("Furniture");
+ product.setDescription("New Desk");
+ productRepository.save(product);
+
+ productRepository.delete(product);
+
+ Product retrievedProduct = productRepository.findOne(product.getId());
+ assertNull(retrievedProduct);
+
+ }
+
+ @Test
+ public void whenFindByName_thenAvailableOnRetrieval() throws Exception {
+ Product phone = new Product();
+ phone.setId("P0001");
+ phone.setName("Phone");
+ phone.setCategory("Electronics");
+ phone.setDescription("New Phone");
+ productRepository.save(phone);
+
+ List retrievedProducts = productRepository.findByName("Phone");
+ assertEquals(phone.getId(), retrievedProducts.get(0).getId());
+ }
+
+ @Test
+ public void whenSearchingProductsByQuery_thenAllMatchingProductsShouldAvialble() throws Exception {
+ final Product phone = new Product();
+ phone.setId("P0001");
+ phone.setName("Smart Phone");
+ phone.setCategory("Electronics");
+ phone.setDescription("New Item");
+ productRepository.save(phone);
+
+ final Product phoneCover = new Product();
+ phoneCover.setId("P0002");
+ phoneCover.setName("Cover");
+ phoneCover.setCategory("Phone");
+ phoneCover.setDescription("New Product");
+ productRepository.save(phoneCover);
+
+ final Product wirelessCharger = new Product();
+ wirelessCharger.setId("P0003");
+ wirelessCharger.setName("Charging Cable");
+ wirelessCharger.setCategory("Cable");
+ wirelessCharger.setDescription("Wireless Charger for Phone");
+ productRepository.save(wirelessCharger);
+
+ Page result = productRepository.findByCustomQuery("Phone", new PageRequest(0, 10));
+ assertEquals(3, result.getNumberOfElements());
+ }
+
+ @Test
+ public void whenSearchingProductsByNamedQuery_thenAllMatchingProductsShouldAvialble() throws Exception {
+ final Product phone = new Product();
+ phone.setId("P0001");
+ phone.setName("Smart Phone");
+ phone.setCategory("Electronics");
+ phone.setDescription("New Item");
+ productRepository.save(phone);
+
+ final Product phoneCover = new Product();
+ phoneCover.setId("P0002");
+ phoneCover.setName("Cover");
+ phoneCover.setCategory("Phone");
+ phoneCover.setDescription("New Product");
+ productRepository.save(phoneCover);
+
+ final Product wirelessCharger = new Product();
+ wirelessCharger.setId("P0003");
+ wirelessCharger.setName("Charging Cable");
+ wirelessCharger.setCategory("Cable");
+ wirelessCharger.setDescription("Wireless Charger for Phone");
+ productRepository.save(wirelessCharger);
+
+ Page result = productRepository.findByNamedQuery("one", new PageRequest(0, 10));
+ assertEquals(3, result.getNumberOfElements());
+ }
+
+}