Soft Deletion with Spring JPA - java

I've done a few changes on my code, because now I want to have a soft deletion instead of a normal one.
I would only need a few JPA annotations for this purpose.
I think I got the right idea, but now I can't even run it because it give the following error:
"""Type mismatch: cannot convert from String to Class<?>"""
My CloudProduct.java ( the one with the error ) :
package com.proj.my.model;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.Id;
import java.sql.Date;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.ParamDef;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.Table;
#Entity
#Table(name="cloud_product_info")
#SQLDelete(sql = "UPDATE cloud_products_info SET deleted = true WHERE id=?")
#FilterDef(name = "deletedProductFilter", parameters = #ParamDef(name = "isDeleted", type = "boolean"))
#Filter(name = "deletedProductFilter", condition = "deleted = :isDeleted")
#EntityListeners(AuditingEntityListener.class)
#JsonIgnoreProperties(value = {"createdAt", "updatedAt"},
allowGetters = true)
public class CloudProduct {
#Id
private String productId;
private String productName;
private String productPrice;
#CreationTimestamp
#Column(updatable = false, name = "created_at")
private Date createdAt;
private boolean deleted = Boolean.FALSE;
public Boolean getDeleted() {
return deleted;
}
public void setDeleted(boolean deleted) {
this.deleted = deleted;
}
public CloudProduct(String productId, String productName, String productPrice, Date createdAt, boolean deleted) {
this.productId = productId;
this.productName = productName;
this.productPrice = productPrice;
this.createdAt = createdAt;
this.deleted = deleted;
}
public CloudProduct() {
}
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getProductPrice() {
return productPrice;
}
public void setProductPrice(String productPrice) {
this.productPrice = productPrice;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
}
The error is implicit on :
#FilterDef(name = "deletedProductFilter", parameters = #ParamDef(name = "isDeleted", type = "boolean"))
Specifically on the "type = "boolean" ".
He is my CloudProductController.java
package com.proj.my.controller;
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.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.proj.my.model.CloudProduct;
import com.proj.my.service.CloudProductService;
#RestController
#RequestMapping("/cloudproduct")
public class CloudProductController
{
CloudProductService cloudProductService;
public CloudProductController(CloudProductService cloudProductService)
{
this.cloudProductService = cloudProductService;
}
#GetMapping("{productId}")
public CloudProduct getCloudProductDetails(#PathVariable("productId") String productId){
return cloudProductService.getCloudProduct(productId);
}
#PostMapping
public String createCloudProductDetails(#RequestBody CloudProduct cloudProduct){
cloudProductService.createCloudProduct(cloudProduct);
return "Success";
}
#PutMapping
public String updateCloudProductDetails(#RequestBody CloudProduct cloudProduct){
cloudProductService.updateCloudProduct(cloudProduct);
return "Updated !";
}
#DeleteMapping("/{productId}")
public void removeOne(#PathVariable("productId") String productId) {
cloudProductService.remove(productId);
}
#GetMapping
public Iterable<CloudProduct> findAll(#RequestParam(value = "isDeleted", required = false, defaultValue = "false") boolean isDeleted) {
return cloudProductService.findAll(isDeleted);
}
}
My CloudProductService.java :
package com.proj.my.service;
import com.proj.my.model.CloudProduct;
public interface CloudProductService {
public String createCloudProduct(CloudProduct cloudProduct);
public String updateCloudProduct(CloudProduct cloudProduct);
public CloudProduct getCloudProduct(String cloudProductId);
public Iterable<CloudProduct> findAll(boolean isDeleted);
public void remove(String cloudProductId);
}
My CloudProductServiceimpl.java :
package com.proj.my.service.impl;
import org.hibernate.Filter;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.proj.my.model.CloudProduct;
import com.proj.my.repository.CloudProductRepository;
import com.proj.my.service.CloudProductService;
import jakarta.persistence.EntityManager;
#Service
public class CloudProductServiceImpl implements CloudProductService
{
CloudProductRepository cloudProductRepository;
#Autowired
private EntityManager entityManager;
public CloudProductServiceImpl(CloudProductRepository cloudProductRepository) {
this.cloudProductRepository = cloudProductRepository;
}
#Override
public String createCloudProduct(CloudProduct cloudProduct){
cloudProductRepository.save(cloudProduct);
return "Success";
}
#Override
public String updateCloudProduct(CloudProduct cloudProduct){
cloudProductRepository.save(cloudProduct);
return "Success";
}
#Override
public CloudProduct getCloudProduct(String cloudProductId){
return cloudProductRepository.findById(cloudProductId).get();
}
public void remove(String cloudProductId){
cloudProductRepository.deleteById(cloudProductId);
}
public Iterable<CloudProduct> findAll(boolean isDeleted){
Session session = entityManager.unwrap(Session.class);
Filter filter = session.enableFilter("deletedProductFilter");
filter.setParameter("isDeleted", isDeleted);
Iterable<CloudProduct> products = cloudProductRepository.findAll();
session.disableFilter("deletedProductFilter");
return products;
}
}
I hope you can help me with this one, THANKS !!!

Related

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Unsatisfied dependency expressed through field 'categoryRepository':

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'categoryService': Unsatisfied dependency expressed through field 'categoryRepository': Error creating bean with name 'categoryRepository' defined in com.example.demo.repository.CategoryRepository defined in #EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Not a managed type: class com.example.demo.model.Category
package com.example.demo.model;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
#Table(name="categories")
public class Category {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "name")
private #NotNull String categoryName;
#Column(name = "description")
private String description;
#Column(name = "image")
private String imageUrl;
public Category() {
}
public Category(#NotNull String categoryName) {
this.categoryName = categoryName;
}
public Category(#NotNull String categoryName, String description) {
this.categoryName = categoryName;
this.description = description;
}
public Category(#NotNull String categoryName, String description, String imageUrl) {
this.categoryName = categoryName;
this.description = description;
this.imageUrl = imageUrl;
}
public String getCategoryName() {
return this.categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#Override
public String toString() {
return "User {category id=" + id + ", category name='" + categoryName + "', description='" + description + "'}";
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
package com.example.demo.controllers;
import java.util.ArrayList;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.service.CategoryService;
import com.example.demo.common.ApiResponse;
import com.example.demo.model.Category;
#RestController
#RequestMapping("category")
public class CategoryController {
#Autowired
private CategoryService categoryService;
#PostMapping("")
public ResponseEntity<ApiResponse> storeCategory(#Valid #RequestBody Category category) {
categoryService.saveCategory(category);
ArrayList<String> message = new ArrayList<String>();
message.add("Category is added successfully");
return new ResponseEntity<ApiResponse>(new ApiResponse(true, message), HttpStatus.OK);
}
}
package com.example.demo.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.example.demo.model.Category;
import com.example.demo.repository.CategoryRepository;
#Service
public class CategoryService {
#Autowired
private CategoryRepository categoryRepository;
public void saveCategory(Category category) {
// categoryRepository.saveAndFlush(category);
}
}
package com.example.demo.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.example.demo.model.Category;
#Repository("categoryRepository")
public interface CategoryRepository extends JpaRepository<Category, Integer> {
Category findByCategoryName(String categoryName);
}
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#SpringBootApplication
#EnableJpaRepositories
#ComponentScan(basePackages = { "com.example.demo.model.*" })
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
how to solve this error?
I ran the program but it showed this error.
Try adding this tag #EnableJpaRepositories in your MainApplication class and #ComponentScan(basePackages = {
"your entities package.*"
}

Test My Restful Web Service in Spring Boot

I'm trying to make a few tests of my CRUD operations in my springboot Restful Web Service, but I can't, because every tutorial I follow ends up with some error !
This time I'm publishing this in order to get some help from you.
My CloudProduct.java
package com.proj.my.model;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import java.sql.Date;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.Table;
#Entity
#Table(name="cloud_product_info")
#SQLDelete(sql = "UPDATE cloud_product_info SET deleted = true WHERE product_id=?")
#Where(clause = "deleted=false")
//#FilterDef(name="", parameters = #ParamDef(name="isDeleted", type = "boolean"))
//#Filter(name="deletedBookFilter", condition = "deleted = :isDeleted")
#EntityListeners(AuditingEntityListener.class)
#JsonIgnoreProperties(value = {"createdAt", "updatedAt"},
allowGetters = true)
public class CloudProduct {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer productId;
private String productName;
private Float priceInEuros;
#CreationTimestamp
#Column(updatable = false, name = "created_at")
private Date createdAt;
private Boolean deleted = Boolean.FALSE;
#JsonIgnore
public Boolean getdeleted() {
return deleted;
}
#JsonIgnore
public void setdeleted(Boolean deleted) {
this.deleted = deleted;
}
public CloudProduct(Integer productId, String productName, Float priceInEuros) {
this.productId = productId;
this.productName = productName;
this.priceInEuros = priceInEuros;
}
public CloudProduct() {
}
public Integer getProductId() {
return productId;
}
public void setProductId(Integer productId) {
this.productId = productId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Float getpriceInEuros() {
return priceInEuros;
}
public void setProductPrice(Float priceInEuros) {
this.priceInEuros = priceInEuros;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
#Override
public String toString() {
return "Product{" +
"id=" + productId +
", name='" + productName + '\'' +
", price=" + priceInEuros +
'}';
}
}
My CloudProductController
package com.proj.my.controller;
import java.util.List;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.proj.my.model.CloudProduct;
import com.proj.my.service.CloudProductService;
#RestController
#RequestMapping("/cloudproduct")
public class CloudProductController
{
CloudProductService cloudProductService;
public CloudProductController(CloudProductService cloudProductService)
{
this.cloudProductService = cloudProductService;
}
#GetMapping("{productId}")
public CloudProduct getCloudProductDetails(#PathVariable("productId") Integer productId){
return cloudProductService.getCloudProduct(productId);
}
#GetMapping("getAll")
public List<CloudProduct> getCloudProductDetails(){
return cloudProductService.getCloudProducts();
}
#PostMapping
public String createCloudProductDetails(#RequestBody CloudProduct cloudProduct){
cloudProductService.createCloudProduct(cloudProduct);
return "Success";
}
#PutMapping
public CloudProduct updateCloudProductDetails(#RequestBody CloudProduct cloudProduct){
return cloudProductService.updateCloudProduct(cloudProduct);
}
#DeleteMapping("{productId}")
public String deleteCloudProductDetails(#PathVariable("productId")Integer productId){
cloudProductService.deleteCloudProduct(productId);
return "Deleted!";
}
}
My CloudProductServiceImpl.java
package com.proj.my.service.impl;
import java.util.List;
import org.springframework.stereotype.Service;
import com.proj.my.model.CloudProduct;
import com.proj.my.repository.CloudProductRepository;
import com.proj.my.service.CloudProductService;
#Service
public class CloudProductServiceImpl implements CloudProductService
{
CloudProductRepository cloudProductRepository;
public CloudProductServiceImpl(CloudProductRepository cloudProductRepository) {
this.cloudProductRepository = cloudProductRepository;
}
#Override
public String createCloudProduct(CloudProduct cloudProduct){
cloudProductRepository.save(cloudProduct);
return "Success";
}
#Override
public CloudProduct updateCloudProduct(CloudProduct cloudProduct){
CloudProduct existingCloudProductDetails = getCloudProduct(cloudProduct.getProductId());
if(cloudProduct.getProductName() != null){
existingCloudProductDetails.setProductName(cloudProduct.getProductName());
}
if(cloudProduct.getpriceInEuros() != null){
existingCloudProductDetails.setProductPrice(cloudProduct.getpriceInEuros());
}
return cloudProductRepository.save(existingCloudProductDetails);
}
#Override
public CloudProduct getCloudProduct(Integer cloudProductId){
return cloudProductRepository.findById(cloudProductId).get();
}
#Override
public String deleteCloudProduct(Integer cloudProductId){
cloudProductRepository.deleteById(cloudProductId);
return "Success";
}
#Override
public List<CloudProduct> getCloudProducts()
{
return cloudProductRepository.findAll();
}
}
My CloudProductService.java
package com.proj.my.service;
import java.util.List;
import com.proj.my.model.CloudProduct;
public interface CloudProductService {
public String createCloudProduct(CloudProduct cloudProduct);
public CloudProduct updateCloudProduct(CloudProduct cloudProduct);
public String deleteCloudProduct(Integer cloudProductId);
public CloudProduct getCloudProduct(Integer cloudProductId);
public List<CloudProduct> getCloudProducts();
}
My cloudProductRepository.java
package com.proj.my.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.proj.my.model.CloudProduct;
public interface CloudProductRepository extends JpaRepository<CloudProduct, Integer> {
}
And finally, my CloudProductControllerTest.java
package com.proj.my.service.impl;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import com.proj.my.controller.CloudProductController;
import com.proj.my.model.CloudProduct;
import com.proj.my.repository.CloudProductRepository;
import com.proj.my.service.CloudProductService;
import java.util.ArrayList;
import java.util.List;
#WebMvcTest(CloudProductController.class)
public class CloudProductControllerTest {
#Autowired
private MockMvc mockMvc;
#Autowired
private ObjectMapper objectMapper;
#MockBean
private CloudProductRepository cloudProductRepository;
#MockBean
private CloudProductService cloudProductService;
#Test
public void testgetCloudProductDetails() throws Exception{
List<CloudProduct> productList = new ArrayList<>();
productList.add(new CloudProduct(1, "Maria", (float) 232));
productList.add(new CloudProduct(2, "Maria", (float) 232));
Mockito.when(cloudProductRepository.findAll()).thenReturn(productList);
String url = "";
mockMvc.perform(get(url)).andExpect(status().isOk());
String actualJsonResponse = mvcResult.getResponse().getContentAsString();
System.out.println(actualJsonResponse);
String expectedJsonResponse = objectMapper.writeValueAsString(productList);
System.out.println(expectedJsonResponse);
assertEquals(actualJsonResponse, expectedJsonResponse);
}
}
And this test is wrong, because the expected here is "[]" and I'm getting " [{"productId":1,"productName":"Maria","priceInEuros":232.0,"createdAt":null},{"productId":2,"productName":"Maria","priceInEuros":232.0,"createdAt":null}]" which is correct... the expected is null, why ?

org.opentest4j.AssertionFailedError: expected: [[]] but was:

I'm trying to make tests of my CRUD operations in my springboot Restful Web Service, but I can't, because every tutorial I follow ends up with some error !
This time I'm publishing this in order to get some help from you.
My CloudProduct.java
package com.proj.my.model;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import java.sql.Date;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.Table;
#Entity
#Table(name="cloud_product_info")
#SQLDelete(sql = "UPDATE cloud_product_info SET deleted = true WHERE product_id=?")
#Where(clause = "deleted=false")
//#FilterDef(name="", parameters = #ParamDef(name="isDeleted", type = "boolean"))
//#Filter(name="deletedBookFilter", condition = "deleted = :isDeleted")
#EntityListeners(AuditingEntityListener.class)
#JsonIgnoreProperties(value = {"createdAt", "updatedAt"},
allowGetters = true)
public class CloudProduct {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer productId;
private String productName;
private Float priceInEuros;
#CreationTimestamp
#Column(updatable = false, name = "created_at")
private Date createdAt;
private Boolean deleted = Boolean.FALSE;
#JsonIgnore
public Boolean getdeleted() {
return deleted;
}
#JsonIgnore
public void setdeleted(Boolean deleted) {
this.deleted = deleted;
}
public CloudProduct(Integer productId, String productName, Float priceInEuros) {
this.productId = productId;
this.productName = productName;
this.priceInEuros = priceInEuros;
}
public CloudProduct() {
}
public Integer getProductId() {
return productId;
}
public void setProductId(Integer productId) {
this.productId = productId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Float getpriceInEuros() {
return priceInEuros;
}
public void setProductPrice(Float priceInEuros) {
this.priceInEuros = priceInEuros;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
#Override
public String toString() {
return "Product{" +
"id=" + productId +
", name='" + productName + '\'' +
", price=" + priceInEuros +
'}';
}
}
My CloudProductController
package com.proj.my.controller;
import java.util.List;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.proj.my.model.CloudProduct;
import com.proj.my.service.CloudProductService;
#RestController
#RequestMapping("/cloudproduct")
public class CloudProductController
{
CloudProductService cloudProductService;
public CloudProductController(CloudProductService cloudProductService)
{
this.cloudProductService = cloudProductService;
}
#GetMapping("{productId}")
public CloudProduct getCloudProductDetails(#PathVariable("productId") Integer productId){
return cloudProductService.getCloudProduct(productId);
}
#GetMapping("getAll")
public List<CloudProduct> getCloudProductDetails(){
return cloudProductService.getCloudProducts();
}
#PostMapping
public String createCloudProductDetails(#RequestBody CloudProduct cloudProduct){
cloudProductService.createCloudProduct(cloudProduct);
return "Success";
}
#PutMapping
public CloudProduct updateCloudProductDetails(#RequestBody CloudProduct cloudProduct){
return cloudProductService.updateCloudProduct(cloudProduct);
}
#DeleteMapping("{productId}")
public String deleteCloudProductDetails(#PathVariable("productId")Integer productId){
cloudProductService.deleteCloudProduct(productId);
return "Deleted!";
}
}
My CloudProductServiceImpl.java
package com.proj.my.service.impl;
import java.util.List;
import org.springframework.stereotype.Service;
import com.proj.my.model.CloudProduct;
import com.proj.my.repository.CloudProductRepository;
import com.proj.my.service.CloudProductService;
#Service
public class CloudProductServiceImpl implements CloudProductService
{
CloudProductRepository cloudProductRepository;
public CloudProductServiceImpl(CloudProductRepository cloudProductRepository) {
this.cloudProductRepository = cloudProductRepository;
}
#Override
public String createCloudProduct(CloudProduct cloudProduct){
cloudProductRepository.save(cloudProduct);
return "Success";
}
#Override
public CloudProduct updateCloudProduct(CloudProduct cloudProduct){
CloudProduct existingCloudProductDetails = getCloudProduct(cloudProduct.getProductId());
if(cloudProduct.getProductName() != null){
existingCloudProductDetails.setProductName(cloudProduct.getProductName());
}
if(cloudProduct.getpriceInEuros() != null){
existingCloudProductDetails.setProductPrice(cloudProduct.getpriceInEuros());
}
return cloudProductRepository.save(existingCloudProductDetails);
}
#Override
public CloudProduct getCloudProduct(Integer cloudProductId){
return cloudProductRepository.findById(cloudProductId).get();
}
#Override
public String deleteCloudProduct(Integer cloudProductId){
cloudProductRepository.deleteById(cloudProductId);
return "Success";
}
#Override
public List<CloudProduct> getCloudProducts()
{
return cloudProductRepository.findAll();
}
}
My CloudProductService.java
package com.proj.my.service;
import java.util.List;
import com.proj.my.model.CloudProduct;
public interface CloudProductService {
public String createCloudProduct(CloudProduct cloudProduct);
public CloudProduct updateCloudProduct(CloudProduct cloudProduct);
public String deleteCloudProduct(Integer cloudProductId);
public CloudProduct getCloudProduct(Integer cloudProductId);
public List<CloudProduct> getCloudProducts();
}
My cloudProductRepository.java
package com.proj.my.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.proj.my.model.CloudProduct;
public interface CloudProductRepository extends JpaRepository<CloudProduct, Integer> {
}
And finally, my CloudProductControllerTest.java
package com.proj.my.service.impl;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import com.proj.my.controller.CloudProductController;
import com.proj.my.model.CloudProduct;
import com.proj.my.repository.CloudProductRepository;
import com.proj.my.service.CloudProductService;
import java.util.ArrayList;
import java.util.List;
#WebMvcTest(CloudProductController.class)
public class CloudProductControllerTest {
#Autowired
private MockMvc mockMvc;
#Autowired
private ObjectMapper objectMapper;
#MockBean
private CloudProductRepository cloudProductRepository;
#MockBean
private CloudProductService cloudProductService;
#Test
public void testgetCloudProductDetails() throws Exception{
List<CloudProduct> productList = new ArrayList<>();
productList.add(new CloudProduct(1, "Maria", (float) 232));
productList.add(new CloudProduct(2, "Maria", (float) 232));
Mockito.when(cloudProductRepository.findAll()).thenReturn(productList);
String url = "";
mockMvc.perform(get(url)).andExpect(status().isOk());
String actualJsonResponse = mvcResult.getResponse().getContentAsString();
System.out.println(actualJsonResponse);
String expectedJsonResponse = objectMapper.writeValueAsString(productList);
System.out.println(expectedJsonResponse);
assertEquals(actualJsonResponse, expectedJsonResponse);
}
}
And this test is wrong, because the expected here is "[]" and I'm getting " [{"productId":1,"productName":"Maria","priceInEuros":232.0,"createdAt":null},{"productId":2,"productName":"Maria","priceInEuros":232.0,"createdAt":null}]" which is correct... the expected is null, why ?

DeleteById Not working in Spring boot JPA Repository

I have two entities- User and Notes. One User can have multiple Notes. I am trying to implement a soft delete for both the tables. For the User table, it is working fine but for Notes table, calling deleteById is not changing the value of the deleted column to true. I tried returning findById(notesId) and it's returning right row but delete is not working.
package com.we.springmvcboot.Model;
import java.util.ArrayList;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import antlr.collections.List;
#Entity
#Table(name="User")
#SQLDelete(sql = "Update User set deleted = 'true' where UserID=?")
#Where(clause = "deleted = 'false'")//FALSE
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long UserID;
#Column(name="emailid")
private String emailID;
#Column(name="deleted")
private String deleted="false";
#OneToMany(mappedBy="user", fetch = FetchType.EAGER,cascade=CascadeType.ALL, orphanRemoval=true)
private Set<Notes> usernotes;
public User() {}
public User(String emailID) {
super();
this.emailID = emailID;
}
public String getDeleted() {
return deleted;
}
public void setDeleted(String deleted) {
this.deleted = deleted;
}
public long getUserID() {
return UserID;
}
public void setUserID(long userID) {
UserID = userID;
}
public String getemailID() {
return emailID;
}
public void setemailID(String emailID) {
this.emailID = emailID;
}
public Set<Notes> getUsernotes() {
return usernotes;
}
public void setUsernotes(Set<Notes> usernotes) {
this.usernotes = usernotes;
}
}
package com.we.springmvcboot.Model;
import java.sql.Date;
import java.util.ArrayList;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import com.fasterxml.jackson.annotation.JsonIgnore;
#Entity
#Table(name="Notes")
#SQLDelete(sql = "Update Notes set deleted = 'true' where NotesID = ?")
#Where(clause = "deleted = 'false'")
public class Notes {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long NotesID;
#Column(name="title")
private String title;
#Column(name="message")
private String message;
#Column(name="date")
private String date;
#Column(name="deleted")
private String deleted="false";
#Column(name="label")
private int label=1;
#ManyToOne()
#JoinColumn(name = "UserID", nullable = false)
private User user;
public Notes() {}
public Notes(String title, String message, String date, User user, int label) {
super();
this.title = title;
this.message = message;
this.date = date;
this.user = user;
this.label=label;
}
public Notes(long notesID, String title, String message, String date, int label) {
super();
NotesID = notesID;
this.title = title;
this.message = message;
this.date = date;
this.label=label;
}
public String getDeleted() {
return deleted;
}
public void setDeleted(String deleted) {
this.deleted = deleted;
}
public int getLabel() {
return label;
}
public void setLabel(int label) {
this.label = label;
}
public long getNotesID() {
return NotesID;
}
public void setNotesID(long notesID) {
NotesID = notesID;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public void setUser(User user) {
this.user = user;
}
}
package com.we.springmvcboot.Service;
import com.we.springmvcboot.Model.*;
import com.we.springmvcboot.exception.*;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import com.we.springmvcboot.Repository.NotesRepository;
import com.we.springmvcboot.Repository.UserRepository;
#Service
public class TodoService {
#Autowired
UserRepository userrepo;
#Autowired
NotesRepository notesrepo;
public Object deleteNote(Map<String, Object> input) throws InvalidInputException, NoteNotFoundException {
long userID;
try {
userID = ((Number) input.get("userID")).longValue();
} catch (Exception e) {
throw new InvalidInputException("Missing UserID");
}
HashMap<String, Object> map = new HashMap<>();
long notesID = ((Number) input.get("notesID")).longValue();
System.out.println(notesID);
if (!notesrepo.findById(notesID).isPresent())
throw new NoteNotFoundException("Invalid Notes ID");
**notesrepo.deleteById(notesID);**
map.put("status", 200);
map.put("message", "Request Successful");
map.put("data", null);
return map;
}
public Object deleteUser(Map<String, Object> input) throws NoteNotFoundException {
HashMap<String, Object> map = new HashMap<>();
long userID;
userID = ((Number) input.get("userID")).longValue();
if (!userrepo.findById(userID).isPresent())
throw new NoteNotFoundException("Invalid User ID");
userrepo.deleteById(userID);
map.put("status", 200);
map.put("message", "Request Successful");
map.put("data", null);
return map;
}
}
Try with #NamedQuery instead of #SQLDelete
or
try with
repo.deleteInBatch(list)

Spring Boot JPA relationship mapping and join queries

Started learning Spring Boot, JPA. Finding difficult on understanding JPA relationship concepts, I tried joining two tables but could not achieve the expected result can anyone help me to get the expected result.
Below Requirement
Have two tables as below
product_master table
product_catagory table
ProductMasterModel
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "product_master")
public class ProductMasterModel {
#Id
#GeneratedValue
#Column(name = "product_id")
private int productId;
#Column(name = "product_name")
private String productName;
#Column(name = "product_category_id")
private int productCategoryId;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "product_category_id", referencedColumnName = "product_catogory_id",insertable = false, updatable = false)
private ProductCatagoryMasterModel productCatagoryMasterModel;
public int getProductId() {
return productId;
}
public void setProductId(int productId) {
this.productId = productId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public int getProductCategoryId() {
return productCategoryId;
}
public void setProductCategoryId(int productCategoryId) {
this.productCategoryId = productCategoryId;
}
public ProductMasterModel() {
super();
}
public ProductMasterModel(String productName, int productCategoryId) {
super();
this.productName = productName;
this.productCategoryId = productCategoryId;
}
}
ProductCatagoryMasterModel
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table (name="product_catagory")
public class ProductCatagoryMasterModel {
#Id
#GeneratedValue
#Column(name="product_catogory_id")
private int productCategoryId;
#Column(name="product_type")
private String productType;
#OneToOne(mappedBy = "productCatagoryMasterModel")
private ProductMasterModel productMasterModel;
public int getProductCategoryId() {
return productCategoryId;
}
public void setProductCategoryId(int productCategoryId) {
this.productCategoryId = productCategoryId;
}
public String getProductType() {
return productType;
}
public void setProductType(String productType) {
this.productType = productType;
}
public ProductCatagoryMasterModel() {
super();
}
public ProductCatagoryMasterModel(String productType) {
super();
this.productType = productType;
}
}
ProductMasterRepository
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.lollipop.model.ProductMasterModel;
#Repository
public interface ProductMasterRepository extends CrudRepository<ProductMasterModel, Integer> {
#Query (value = "select * from product_master pm, product_catagory pc where pc.product_catogory_id = pm.product_category_id", nativeQuery = true)
public List $ProductMasterModel$ getProductCategoryDetail();
}
ProductService
import java.util.List;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.lollipop.model.ProductMasterModel;
import com.lollipop.repository.ProductMasterRepository;
#Service
#Transactional
public class ProductService {
#Autowired
private ProductMasterRepository productMasterRepository;
public void getProductCat() {
List $ProductMasterModel$ productMasterModel = productMasterRepository.getProductCategoryDetail();
System.out.println("productMasterModel value "+productMasterModel.toString());
}
}
When calling getProductCat() method getting result as
productMasterModel value [ProductMasterModel [productId=1011,
productName=Pencil, productCategoryId=10], ProductMasterModel
[productId=1012, productName= Mobile, productCategoryId=11]]
Since ProductMasterModel is not having productType variable it is not displaying productType
I need below result by joining two tables, please help me to acheive this
[[productName=Pencil,productType=Stationary],[productName=
Mobile,productType=Electronics]]
Yes, One to One Relationship should work.
Changes should be made in your POJO.
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "product_master")
public class ProductMasterModel {
#Id
#GeneratedValue
#Column(name = "product_id")
private int productId;
#Column(name = "product_name")
private String productName;
#Column(name = "product_category_id")
private int productCategoryId;
#OneToOne(mappedBy= product_master, fetch = FetchType.LAZY)
public ProductCatagoryMasterModel productCatagory;
public int getProductId() {
return productId;
}
public void setProductId(int productId) {
this.productId = productId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public int getProductCategoryId() {
return productCategoryId;
}
public void setProductCategoryId(int productCategoryId) {
this.productCategoryId = productCategoryId;
}
public ProductMasterModel() {
}
public ProductMasterModel(String productName, int productCategoryId) {
super();
this.productName = productName;
this.productCategoryId = productCategoryId;
}
}
Next Address your Category Model
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table (name="product_catagory")
public class ProductCatagoryMasterModel {
#Id
#GeneratedValue
#Column(name="product_catogory_id")
private int productCategoryId;
#Column(name="product_type")
private String productType;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "product_master", referencedColumnName = "product_id")
private ProductMasterModel productMaster;
public int getProductCategoryId() {
return productCategoryId;
}
public void setProductCategoryId(int productCategoryId) {
this.productCategoryId = productCategoryId;
}
public String getProductType() {
return productType;
}
public void setProductType(String productType) {
this.productType = productType;
}
public ProductCatagoryMasterModel() {
super();
}
public ProductCatagoryMasterModel(String productType) {
super();
this.productType = productType;
}
}
We also need DAO
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.lollipop.model.ProductMasterModel;
#Repository
public interface ProductMasterRepository extends CrudRepository<ProductMasterModel, Integer> {
}
Product Service
import java.util.List;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.lollipop.model.ProductMasterModel;
import com.lollipop.repository.ProductMasterRepository;
#Service
#Transactional
public class ProductService {
#Autowired
private ProductMasterRepository productMasterRepository;
public List<ProductMasterModel > getAllProducts() {
return productMasterRepository.findAll();
}
public Optional<ProductMasterModel > getProductById(int productId) {
if (!productMasterRepository.existsById(productId)) {
throw new ResourceNotFoundException("Product with id " + productId+ " not found");
}
return productMasterRepository.findById(productId);
}
}
}
You need to establish ont-to-one relationship between those two tables.
Take a look at this:
Example

Categories