[FIXED] how to fetch data based on condition in Spring Data JPA?

Issue

My requirement is to fetch data from DB based on some condition, as of now i have done the fetch operation using FindAll() and Find() methods which are fine when it comes to fetch all the records or single record from the DB but I’m unable to find any way to fetch data based on condition like we do in hibernate criteria.

Here’s my code of Fetch operation in Spring Data JPA:

Controller:

package com.iep.projectentityservice.controller;

import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
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.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.iep.projectentityservice.DTO.ProductDto;
import com.iep.projectentityservice.service.ProductService;

@RestController
@CrossOrigin
public class ProductController 
{
    private static final Logger LOGGER = LogManager.getLogger();

    @Autowired
    ProductService productService;

@GetMapping("/fetchproductdata")
    public ResponseEntity<List<ProductDto>> fetchProductData()
    {
        List<ProductDto> lstProduct = productService.fetchProductData();
        
        if(lstProduct != null && lstProduct.size() > 0)
        {
            return new ResponseEntity<>(lstProduct,HttpStatus.OK);
        }
        else
        {
            return new ResponseEntity<>(lstProduct,HttpStatus.NOT_FOUND); 
        }
    }
}

Service:

package com.iep.projectentityservice.service;

import java.util.ArrayList;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.iep.projectentityservice.DTO.ProductDto;
import com.iep.projectentityservice.blueprint.schema.Products;
import com.iep.projectentityservice.dao.ProductRepository;

@Transactional
@Service
public class ProductServiceImpl implements ProductService
{
    /** The Constant LOGGER. */
    private static final Logger LOGGER = LogManager.getLogger();
    
    /** The project entity DAO. */
    @Autowired
    ProductRepository productRepository;

@Override
    public List<ProductDto> fetchProductData() 
    {
        LOGGER.info("fetchProductData service called");
        
        List<ProductDto> lstProduct = null;
        
        try
        {
            lstProduct = new ArrayList<>();
            
            List<Products> lstProductDetails = productRepository.findAll();
            
            if(lstProductDetails != null && lstProductDetails.size() > 0)
            {
                for(int i = 0 ; i < lstProductDetails.size() ; i++)
                {
                    Products product = lstProductDetails.get(i);
                    ProductDto productDto = new ProductDto();
                    
                    productDto.setId(product.getId());
                    productDto.setProductName(product.getProductName());
                    productDto.setDescription(product.getDescription());
                    productDto.setPrice(product.getPrice());
                    productDto.setQuantity(product.getQuantity());
                    
                    lstProduct.add(productDto);
                }
            }
        }
        catch (Exception e) 
        {
            LOGGER.error("Exception in fetchProductData service");
        }
        return lstProduct;
    }
}

Repository:


package com.iep.projectentityservice.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import com.iep.projectentityservice.blueprint.schema.Products;

public interface ProductRepository extends JpaRepository<Products, Long>{
}

Entity:

package com.iep.projectentityservice.blueprint.schema;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "product_details")
public class Products 
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    private String productName;
    private String description;
    private String price;
    private String quantity;
    
    
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getProductName() {
        return productName;
    }
    public void setProductName(String productName) {
        this.productName = productName;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public String getPrice() {
        return price;
    }
    public void setPrice(String price) {
        this.price = price;
    }
    public String getQuantity() {
        return quantity;
    }
    public void setQuantity(String quantity) {
        this.quantity = quantity;
    }
}

DTO:

package com.iep.projectentityservice.DTO;


public class ProductDto 
{
        private long id;
        private String productName;
        private String description;
        private String price;
        private String quantity;
        
        public long getId() {
            return id;
        }
        public void setId(long id) {
            this.id = id;
        }
        public String getProductName() {
            return productName;
        }
        public void setProductName(String productName) {
            this.productName = productName;
        }
        public String getDescription() {
            return description;
        }
        public void setDescription(String description) {
            this.description = description;
        }
        public String getPrice() {
            return price;
        }
        public void setPrice(String price) {
            this.price = price;
        }
        public String getQuantity() {
            return quantity;
        }
        public void setQuantity(String quantity) {
            this.quantity = quantity;
        }
}

As I’m doing in the code, fetching all the records but not able to find a way to add some restriction or criteria conditions like hibernate in Data JPA while fetching.

So, is there anyway to add restrictions to Spring Data JPA fetch operation?

Solution

There are 4 main options

  1. Query method naming
  2. Use JPQL
  3. Use Native Query
  4. Named Queries

Find the additional links here

(https://www.baeldung.com/spring-data-jpa-query)

(https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation)

(https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods)

    
public interface ProductRepository extends JpaRepository<Products, Long>{
     //Method Naming convention
     Products findByProductName(String productName);

     //JPQL
     @Query("SELECT p FROM Products p WHERE p.productName = ?1")
     Collection<Products> findAllProductsByName(String productName);

     //Native Query
     @Query(value = "SELECT * FROM Products p WHERE p.productName = ?1", 
     nativeQuery = true)
     Collection<Products> findProductsByName(String productName);
}

Answered By – anantha ramu

Answer Checked By – Marie Seifert (Easybugfix Admin)

Leave a Reply

(*) Required, Your email will not be published