NoSQL Zone is brought to you in partnership with:

I have more than 10years of development experience. My expertise is in Java EE technology, object-oriented application development, and use of open source frameworks. In recent years, I mainly worked in development projects of Java EE applications in Weblogic platform with Oracle database. I primarily involved in framework development and architectural design in these projects. Boris is a DZone MVB and is not an employee of DZone and has posted 13 posts at DZone. You can read more from them at their website. View Full User Profile

Sample Apps: Spring data MongoDB and JSF Integration tutorial (Part 4)

02.16.2013
| 3497 views |
  • submit to reddit

Enquriy data with spring data repository and mongotemplate
Spring Data Repository:
Spring Data repository abstraction reduces the boilerplate code to write the data access layer of the application. Automatic implementation of Repository interfaces provides simple operation on mongoDB. It helps our product save and delete function make

MongoTemplate:
MongoTemplate offers convenience operations to create, update, delete and query for MongoDB documents and provides a mapping between your domain objects and MongoDB documents. In our application, since the spring data repository cannot fulfill the requirement of searching function, we use MongoTemplate to archive the searching capability.

Customizing Spring Data Repository
Since the searching of product cannot be easily implement with Spring data repository abstraction, we would like to implements the multi-criteira product search with MongoDBTemplate. To enrich Spring data repository with MongoTemplate, we can do the following to customize the repository:

ProductRepository.java

package com.borislam.repository;
 
import java.util.List;
import org.springframework.data.repository.PagingAndSortingRepository;
import com.borislam.domain.Product;
 
public interface ProductRepository  extends PagingAndSortingRepository<Product, String> , ProductRepostitoryCustom{
  
 List<product> findByType(String type);
 List<product> findByTypeAndTitle(String type, String title); 
 Product findBySku(String sku);
}

ProductRepositoryCustom.java

package com.borislam.repository;
 
import java.util.List;
import com.borislam.domain.Product;
import com.borislam.view.ProductSearchCriteria;
 
 
public interface ProductRepostitoryCustom {
 public List<product> searchByCriteria(ProductSearchCriteria criteria);
  
}

ProductRepositoryImpl.java

package com.borislam.repository.impl;
 
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.util.StringUtils;
import com.borislam.domain.Product;
import com.borislam.repository.ProductRepostitoryCustom;
import com.borislam.view.ProductSearchCriteria;
 
public class ProductRepositoryImpl implements ProductRepostitoryCustom{
  
 @Autowired
 private MongoTemplate mongoTemplate;
  
 @Override
 public List<product> searchByCriteria(ProductSearchCriteria criteria) {
  Query query = new Query();
  if ( StringUtils.hasText(criteria.getSku())) 
  { 
   Criteria c = Criteria.where("sku").is(criteria.getSku());
   query.addCriteria(c);
  }
  if (StringUtils.hasText(criteria.getTitle())) {
   Criteria c = Criteria.where("title").regex(".*" + criteria.getTitle() + ".*", "i");
   query.addCriteria(c);
  }
  if (StringUtils.hasText(criteria.getDescription())) {
   Criteria c = Criteria.where("description").regex(".*" + criteria.getDescription() + ".*", "i");
   query.addCriteria(c);
  }
  if (StringUtils.hasText(criteria.getProductType())) {
   Criteria c = Criteria.where("type").is(criteria.getProductType());
   query.addCriteria(c);
    
  }  
  if (StringUtils.hasText(criteria.getTrack())) {
   Criteria c = Criteria.where("details.tracks").regex(".*" + criteria.getTrack() + ".*", "i");
   query.addCriteria(c);
  }
  if (StringUtils.hasText(criteria.getChapter())) {
   Criteria c = Criteria.where("details.chapters").regex(".*" + criteria.getChapter() + ".*", "i");
   query.addCriteria(c);
  }
  return mongoTemplate.find(query, Product.class);
 }
  
  
}

Data Model:
Product.java

package com.borislam.domain;
 
public class Product {
  private String id;
  private String sku ;
  private String  type;
  private String title;
  private String description;
  private String publisher;
  private Pricing pricing;
  private Detail details;
 public String getId() {
  return id;
 }
 public void setId(String id) {
  this.id = id;
 }
 public String getSku() {
  return sku;
 }
 public void setSku(String sku) {
  this.sku = sku;
 }
 public String getType() {
  return type;
 }
 public void setType(String type) {
  this.type = type;
 }
 public String getTitle() {
  return title;
 }
 public void setTitle(String title) {
  this.title = title;
 }
 public String getDescription() {
  return description;
 }
 public void setDescription(String description) {
  this.description = description;
 }
 public String getPublisher() {
  return publisher;
 }
 public void setPublisher(String publisher) {
  this.publisher = publisher;
 }
 public Pricing getPricing() {
  return pricing;
 }
 public void setPricing(Pricing pricing) {
  this.pricing = pricing;
 }
 public Detail getDetails() {
  return details;
 }
 public void setDetails(Detail details) {
  this.details = details;
 }    
}

Pricing.java

package com.borislam.domain;
 
 
 
 
public class Pricing {
 private String id;
 private double list;
 private double retail;
 public String getId() {
  return id;
 }
 public void setId(String id) {
  this.id = id;
 }
 public double getList() {
  return list;
 }
 public void setList(double list) {
  this.list = list;
 }
 public double getRetail() {
  return retail;
 }
 public void setRetail(double retail) {
  this.retail = retail;
 }
 public Pricing(double list, double retail) {
  super();
  this.list = list;
  this.retail = retail;
 }
  
}

Detail.java

package com.borislam.domain;
 
import java.util.List;
 
public class Detail {
 private String id;
 private String title;
 private String author;
 private String artist;
 private String genre;
 private List<string> pic;
 private List<string> chapters;
 private List<string> tracks;
 public String getTitle() {
  return title;
 }
 public void setTitle(String title) {
  this.title = title;
 }
 public String getAuthor() {
  return author;
 }
 public void setAuthor(String author) {
  this.author = author;
 }
 public String getGenre() {
  return genre;
 }
 public void setGenre(String genre) {
  this.genre = genre;
 }
 public List<string> getPic() {
  return pic;
 }
 public void setPic(List<string> pic) {
  this.pic = pic;
 }
 public List<string> getChapters() {
  return chapters;
 }
 public void setChapters(List<string> chapters) {
  this.chapters = chapters;
 }
 public String getId() {
  return id;
 }
 public void setId(String id) {
  this.id = id;
 }
 public String getArtist() {
  return artist;
 }
 public void setArtist(String artist) {
  this.artist = artist;
 }
 public List<string> getTracks() {
  return tracks;
 }
 public void setTracks(List<string> tracks) {
  this.tracks = tracks;
 }
  
}

JSF Part:
common.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
 xmlns:h="http://java.sun.com/jsf/html"
 xmlns:f="http://java.sun.com/jsf/core"
 xmlns:ui="http://java.sun.com/jsf/facelets"
 xmlns:p="http://primefaces.org/ui">
 
<f:view contentType="text/html">
 
 <h:head>
 
  <f:facet name="first">
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
   <title><ui:insert name="pageTitle">Page Title</ui:insert></title>
   <ui:insert name="head" />
  </f:facet>
 
 </h:head>
 
 
 <h:body>
  <div style="margin:auto;width:1024px;">
<div id="header" class="ui-widget" >
<div id="logo" style="border:1px  solid #acbece; border-bottom: none; ">
<p:graphicImage   value="/resources/image/mongoshopheader.jpg"/></div>
<div id="logo" style="border:1px solid #acbece;">
<p:menubar style="border:none"><p:menuitem value="Search" url="/search.jsf" icon="ui-icon-search" /><p:menuitem value="New Product" url="/detail.jsf" icon="ui-icon-document" /></p:menubar></div>
</div>
<div id="page" class="ui-widget" style="overflow:hidden;">
<div id="content"  style="display:block">
<ui:insert name="content">...</ui:insert>     
             </div>
</div>
</div>
</h:body>
 
</f:view>
</html>

Search.xhml

<html xmlns="http://www.w3.org/1999/xhtml"
 xmlns:ui="http://java.sun.com/jsf/facelets"
 xmlns:h="http://java.sun.com/jsf/html"
 xmlns:f="http://java.sun.com/jsf/core"
 xmlns:p="http://primefaces.org/ui">
 
 
 <ui:composition template="/template/common.xhtml">
  
  <ui:define name="pageTitle">
   <h:outputText value="Product Search" />
  </ui:define>
  
  <ui:define name="content">
      <h:form id="searchForm">
       <p:growl id="mainGrowl" sticky="true"  /><p:panelGrid style="width:1024px"><f:facet name="header">
     <p:row><p:column colspan="4">Product Search
             </p:column></p:row></f:facet>  
       <p:row><p:column><h:outputLabel for="sku" value="sku: " />
         </p:column><p:column><p:inputText id="sku" value="#{productSearchBean.criteria.sku}" /></p:column><p:column><h:outputLabel for="productType" value="Product Type: " />
         </p:column><p:column><p:selectOneMenu id="productType"   label="Type"   value="#{productSearchBean.criteria.productType}"  ><f:selectItem itemLabel="Select One" itemValue="" />  
                 <f:selectItem itemLabel="Audio Album" itemValue="Audio Album" />  
                 <f:selectItem itemLabel="Book" itemValue="Book" /> 
             </p:selectOneMenu></p:column></p:row><p:row><p:column><h:outputLabel for="title" value="Title: " />
         </p:column><p:column><p:inputText id="title" value="#{productSearchBean.criteria.title}" /></p:column><p:column><h:outputLabel for="description" value="Description: " />
         </p:column><p:column><p:inputText id="description" value="#{productSearchBean.criteria.description}" /></p:column></p:row><p:row><p:column><h:outputLabel for="track" value="Track: " />
         </p:column><p:column><p:inputText id="track" value="#{productSearchBean.criteria.track}" /></p:column><p:column><h:outputLabel for="chapter" value="Chapter: " />
         </p:column><p:column><p:inputText id="chapter" value="#{productSearchBean.criteria.chapter}" /></p:column></p:row></p:panelGrid><p:commandButton value="search" icon="ui-icon-search"  actionListener="#{productSearchBean.doSearch}" update="dataTable"/><hr/><p:dataTable id="dataTable" var="prod" value="#{productSearchBean.productList}"  
     paginator="true" rows="10"><p:column><f:facet name="header">  
                    <h:outputText value="Sku" />  
                </f:facet>  
                <h:outputText value="#{prod.sku}" />  
            </p:column><p:column><f:facet name="header">  
                    <h:outputText value="Type" />  
                </f:facet>  
                <h:outputText value="#{prod.type}" />  
            </p:column><p:column><f:facet name="header">  
                    <h:outputText value="Title" />  
                </f:facet>  
                <h:outputText value="#{prod.title}" />  
            </p:column><p:column><f:facet name="header">  
                    <h:outputText value="Publisher" />  
                </f:facet>  
                <h:outputText value="#{prod.publisher}" />  
            </p:column><p:column><f:facet name="header">  
                    <h:outputText value="Artist" />  
                </f:facet>  
                <h:outputText value="#{prod.details.artist}" />  
            </p:column><p:column><f:facet name="header">  
                    <h:outputText value="Author" />  
                </f:facet>  
                <h:outputText value="#{prod.details.author}" />  
            </p:column></p:dataTable></h:form>
  </ui:define>
 </ui:composition>
</html>

ProductSearchCriteria.java

package com.borislam.view;
 
public class ProductSearchCriteria {
 private String sku;
 private String description;
 private String productType;
 private String track;
 private String chapter;
 private String title;
 public String getSku() {
  return sku;
 }
 public void setSku(String sku) {
  this.sku = sku;
 }
 public String getDescription() {
  return description;
 }
 public void setDescription(String description) {
  this.description = description;
 }
 public String getProductType() {
  return productType;
 }
 public void setProductType(String productType) {
  this.productType = productType;
 }
 public String getTrack() {
  return track;
 }
 public void setTrack(String track) {
  this.track = track;
 }
 public String getTitle() {
  return title;
 }
 public void setTitle(String title) {
  this.title = title;
 }
 public String getChapter() {
  return chapter;
 }
 public void setChapter(String chapter) {
  this.chapter = chapter;
 }
  
}

Service Layer:
ProductService.java

package com.borislam.service;
 
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.borislam.domain.Product;
import com.borislam.repository.ProductRepository;
import com.borislam.view.ProductSearchCriteria;
 
 
@Service
public class ProductService {
  
 @Autowired
 private ProductRepository productRepository;
  
 public List<product> searchByCriteria(ProductSearchCriteria criteria){
  return productRepository.searchByCriteria(criteria);
 }
  
 public Product getProduct(String sku) {
  return productRepository.findBySku(sku);
 }
}


Published at DZone with permission of Boris Lam, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)