Wrong Pageable data displayed in my browser - java

I am trying to display data from MySQL database using spring data with Pageable class. I am new in Spring Data and unfortunately I get all rows shown in my browser, instead of some.
Find below my code
pom.xml
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.5.0.RELEASE</version>
</dependency>
ProductDaoImpl
package com.dao;
import java.util.List;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import com.model.Product;
#Repository
public class ProductDaoImpl implements ProductDao {
#Autowired
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
#SuppressWarnings("unchecked")
public Page<Product> getPageProduct(#Param("libelleProduct")String libelleProduct, Pageable pageable) {
List<Product> listProduct = sessionFactory.getCurrentSession().createQuery("From Product p where p.libelleProduct like :libelleProduct").setParameter("libelleProduct", libelleProduct).list();
Page<Product> pageProduct = new PageImpl<Product>(listProduct, pageable, listProduct.size());
return pageProduct;
}
}
ProductService
package com.service;
import java.util.List;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import com.dao.ProductDao;
import com.model.Product;
#Service
#Transactional
public class ProductServiceImpl implements ProductService {
#Autowired
private ProductDao productDao;
public ProductDao getProductDao() {
return productDao;
}
public Page<Product> getPageProduct(String libelleProduct, int page, int size) {
return productDao.getPageProduct(libelleProduct, new PageRequest(page, size));
}
}
ProductController
package com.controller;
import org.jboss.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.model.Product;
import com.service.ProductService;
#RestController
public class ProductController {
public Logger logger = Logger.getLogger(ProductController.class);
public ProductController(){
System.out.println("ProductController()");
}
#Autowired
private ProductService service;
#RequestMapping(value="/listedesproduit", method=RequestMethod.GET, headers="Accept=application/json")
#ResponseBody
public Page<Product> getPageProduct(){
Page<Product> pageProduct = service.getPageProduct("%e%",0, 1);
pageProduct.forEach(p->System.out.println(p.getLibelleProduct()));
return pageProduct;
}
}
Find below the result I get in my browser, I get four rows shown instead of one on each page.
{"content":[{"idProduct":2,"libelleProduct":"sprite","qteProduct":5},{"idProduct":3,"libelleProduct":"eku","qteProduct":5},{"idProduct":4,"libelleProduct":"33 export","qteProduct":5},{"idProduct":6,"libelleProduct":"guiness","qteProduct":5}],"size":1,"number":0,"numberOfElements":4,"sort":null,"totalPages":4,"totalElements":4,"firstPage":true,"lastPage":false}
Can you please help me to find what I do wrong?

You are using it wrong here:
List<Product> listProduct = sessionFactory.getCurrentSession()
.createQuery("From Product p where p.libelleProduct like :libelleProduct")
.setParameter("libelleProduct", libelleProduct).list();
Page<Product> pageProduct = new PageImpl<Product>(listProduct, pageable, listProduct.size());
You are basically loading all the query results and then returning it in a PageImpl, which is just a wrapper of the data.
You should create a PagingAndSortingRepository and call query methods passing the Pageable, which is the page request to be executed by the repository.
If this doesn't make sense to you, look for tutorials about "spring data paging" like this one and take a look at the documentation.

Related

Consider defining a bean of type 'com.fsse2207.project_backend.service.ProductService' in your configuration

Basically, I have created all of the pojo and layers(including the repository layer) necessary for Spring Boot to automatically implement MySql commands. When I trying to run the programme, I get the following command:
Description:
Parameter 0 of constructor in com.fsse2207.project_backend.api.ProductApi required a bean of type 'com.fsse2207.project_backend.service.ProductService' that could not be found.
Action:
Consider defining a bean of type 'com.fsse2207.project_backend.service.ProductService' in your configuration.
It turns out there's sth wrong about the bean in my ProductApi. It says "
Could not autowire. No beans of 'ProductService' type found." How do I fix it?
The following is the interface under the service layer:
package com.fsse2207.project_backend.service;
import com.fsse2207.project_backend.data.ProductCreateData;
import com.fsse2207.project_backend.data.ProductDetailData;
import com.fsse2207.project_backend.exception.ProductFoundByIdException;
import org.springframework.stereotype.Service;
public interface ProductService {
ProductDetailData createProductData (ProductCreateData productCreateData) throws ProductFoundByIdException;
}
The following is the service class:
package com.fsse2207.project_backend.service.impl;
import com.fsse2207.project_backend.data.ProductCreateData;
import com.fsse2207.project_backend.data.ProductDetailData;
import com.fsse2207.project_backend.data.entity.ProductEntity;
import com.fsse2207.project_backend.exception.ProductFoundByIdException;
import com.fsse2207.project_backend.repository.ProductRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class ProductServiceImpl {
private ProductRepository productRepository;
#Autowired
public ProductServiceImpl(ProductRepository productRepository){
this.productRepository=productRepository;
}
public ProductDetailData createProductData (ProductCreateData productCreateData) throws ProductFoundByIdException {
ProductEntity productEntity=new ProductEntity(productCreateData);
if(productRepository.existsById(productEntity.getpId())){
throw new ProductFoundByIdException();
}
return new ProductDetailData(productRepository.save(productEntity));
}
}
The following is the Api:
package com.fsse2207.project_backend.api;
import com.fsse2207.project_backend.data.ProductCreateData;
import com.fsse2207.project_backend.data.ProductDetailData;
import com.fsse2207.project_backend.data.dto.CreateRequestDto;
import com.fsse2207.project_backend.data.dto.CreateResponseDto;
import com.fsse2207.project_backend.exception.ProductFoundByIdException;
import com.fsse2207.project_backend.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class ProductApi {
private ProductService productService;
#Autowired
public ProductApi(ProductService productService){
this.productService=productService;
}
#PostMapping
public CreateResponseDto createResponseDto(#RequestBody CreateRequestDto createRequestDto) throws ProductFoundByIdException {
ProductCreateData productCreateData=new ProductCreateData(createRequestDto);
ProductDetailData productDetailData =productService.createProductData(productCreateData);
return new CreateResponseDto(productDetailData);
}
}
I found the problem:
I didn't add the implements keyword in the class definition of ProductServiceImpl so it was not connected to the bean, aka the interface, aka the service layer.
First of all you should not add annotation #Service for ProductService interface.
Moreover this can happen when you have your Class Application in "another package".
You can solve the problem using annotation #ComponentScan (basePackages = {"your.company.domain.package"})

How to properly #Autowire a component in a Spring Boot App

I'm putting together a simple Spring Boot app, and having an issue with an #Autowired field not "showing up".
My main app class:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class SpringElasticCatalogApi {
public static void main(String[] args) {
SpringApplication.run(SpringElasticCatalogApi.class, args);
}
}
My Repository class:
import com.discover.harmony.elastic.model.Customer;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Component;
import java.util.List;
#Component
public interface CustomerRepository extends ElasticsearchRepository<Customer, String> {
public Customer findByFirstName(String firstName);
public List<Customer> findByLastName(String lastName);
}
This class ("Loaders") requires an #Autowired repository field, which is NULL:
import com.discover.harmony.elastic.model.BusinessMetadata;
import com.discover.harmony.elastic.model.Customer;
//import com.discover.harmony.elastic.repository.CustomerRepository;
import com.discover.harmony.elastic.api.CustomerRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
//#Configuration
#Component
public class Loaders {
#Autowired
private CustomerRepository repository;
#PostConstruct
#Transactional
public void loadAll(){
this.repository.deleteAll();
saveCustomers();
fetchAllCustomers();
fetchIndividualCustomers();
}
private void saveCustomers() {
this.repository.save(new Customer("Alice", "Smith"));
this.repository.save(new Customer("Bob", "Smith"));
}
private void fetchAllCustomers() {
System.out.println("Customers found with findAll():");
System.out.println("-------------------------------");
for (Customer customer : this.repository.findAll()) {
System.out.println(customer);
}
System.out.println();
}
private void fetchIndividualCustomers() {
System.out.println("Customer found with findByFirstName('Alice'):");
System.out.println("--------------------------------");
System.out.println(this.repository.findByFirstName("Alice"));
System.out.println("Customers found with findByLastName('Smith'):");
System.out.println("--------------------------------");
for (Customer customer : this.repository.findByLastName("Smith")) {
System.out.println(customer);
}
}
private List<BusinessMetadata> getData() {
List<BusinessMetadata> metadata = new ArrayList<>();
metadata.add(new BusinessMetadata((long)1,"TradeLine"));
metadata.add(new BusinessMetadata((long)2,"Credit Line"));
metadata.add(new BusinessMetadata((long)3,"Other Line"));
return metadata;
}
}
What should I change, to make the #Autowire work as expected here?
The problem is that your example is not complete on implementing the ElasticSearch. To proof this, turn your CustomerRepository into a class and remove ElasticsearchRepository<Customer, String> then everything goes fine.
What you need to do is adding a new Configuration class, with #EnableElasticsearchRepositories(basePackages = "com.discover.harmony.elastic.api.CustomerRepository") to scan the provided package for Spring Data repositories.
You can find a complete example here.

Dependency Injection in JHipster with Mybatis

I have little problem with Spring and Mybatis connection in JHipster framework( (out of the box).
Problem is occurred when I try inject class, which have Mybatis mapper injected. In this situation class returns null pointer exception. When I try to autowire this class I get "cannot find candidate to autowire error".
Architecture of class:
Repository(Mybatis mapper interface) ->
ServiceImplementation (Class with injected Mybatis Repository, business logic) ->
Resource (REST controller with instance of Service)
I think solution is simple, but I cannot find right implementation:
Service Implementation is invisible for Spring Beans Mapper and I
can't find in JHipster configuration for them.
I have to use another annotation to get right injection of Service
Implemenation
Somebody meet with this situation and can get litte clue for me to refactor my code? :-) Thanks
Code:
Repository
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.apache.ibatis.annotations.Insert;
import java.util.List;
import org.apache.ibatis.annotations.Delete;
import pl.xxx.xxx.domain.City;
import pl.xxx.xxx.domain.Dish;
#Mapper
public interface CityMapper {
#Select("SELECT * FROM CITY WHERE id = #{id}")
City getCityByID(#Param("id") Long id);
#Select("SELECT * FROM CITY WHERE name = #{name}")
City getCityByName(#Param("name") String name);
#Insert("INSERT INTO CITY('name') VALUES(#{name})")
void createCity(City city);
#Delete("DELETE FROM CITY WHERE id = #{id}")
void deleteCityByID(City city);
#Select("SELECT count(*) FROM CITY")
int getNumberOfCities();
#Select("<script>"
+ "SELECT * FROM CITY "
+ "</script>")
List<City> findAll();
}
Service
package pl.xxx.xxx.service.impl;
import java.util.List;
import javax.inject.Inject;
import pl.xxxx.xxxx.domain.City;
import pl.xxxx.xxx.repository.CityMapper;
import pl.xxx.xxx.service.CityService;
import pl.xxx.xxx.web.rest.util.Pageable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.context.annotation.Bean;
#Service
#Transactional
public class CityServiceImpl implements CityService {
#Inject
private CityMapper cityMapper;
#Override
public List<City> findAll(Pageable pageable) {
return cityMapper.findAll();
}
}
Interface
package pl.xxx.xxx.service;
import java.util.List;
import pl.xxx.xxx.domain.City;
import pl.xxxx.xxx.domain.Dish;
import pl.xxx.xxx.web.rest.util.Pageable;
public interface CityService {
/**
* Get all the dishes.
*
* #param pageable the pagination information
* #return the list of entities
*/
List<City> findAll(Pageable pageable);
}
Resource
package pl.xxx.xxxx.web.rest;
import com.codahale.metrics.annotation.Timed;
import pl.xxx.xxx.xxx.City;
import pl.xxx.xxx.domain.Dish;
import pl.xxx.xxx.repository.CityMapper;
import pl.xxx.xxx.service.impl.CityServiceImpl;
import pl.xxx.xxx.web.rest.util.Pageable;
import pl.xxx.xxx.web.rest.util.PaginationUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import javax.annotation.Resource;
import javax.inject.Inject;
import static org.elasticsearch.index.query.QueryBuilders.*;
/**
* REST controller for managing City.
*/
#RestController
#RequestMapping("/api")
public class CityResource {
private final Logger log = LoggerFactory.getLogger(CityResource.class);
private CityServiceImpl cityServiceImpl;
#Inject
private CityMapper cityMapper;
/**
* GET /Cities: get all the cities.
*
* #param pageable the pagination information
* #return the ResponseEntity with status 200 (OK) and the list of citires in body
* #throws URISyntaxException if there is an error to generate the pagination HTTP getHeaders()
*/
#RequestMapping(value = "/cities",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed()
public ResponseEntity<List<City>> getAllCities(Pageable pageable)
throws URISyntaxException {
log.debug("REST request to get a page of Cities");
Pageable p = new Pageable();
List<City> page = cityServiceImpl.findAll(p);
HttpHeaders headers = PaginationUtil.generateSearchPaginationHttpHeadersLM("/api/cities");
return new ResponseEntity<>(page, headers, HttpStatus.OK);
}
}

Pageable and PageRequest Issue

Hey everyone i have been trying to make this tutorial in youtube about spring boot and angular js https://www.youtube.com/watch?v=zBLXWIhrg7U
i have some trouble with using pageRequest Page<> in Java ps this is my controller
package cat.Controller;
import cat.dao.ProduitRepository;
import cat.entities.Produit;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class ProduitController {
#Autowired
private ProduitRepository produitRepository ;
#RequestMapping("/test")
public String test() {
return "test";
}
#RequestMapping("/save")
public Produit saveProduit(Produit p)
{
produitRepository.save(p);
return p ;
}
#RequestMapping("/all")
public List<Produit> getProduits()
{
return produitRepository.findAll();
}
#RequestMapping("/produit")
public Page<Produit> getProduits(int page)
{
return produitRepository.findAll(new PageRequest(page, 5));
}
**#RequestMapping("/produict")
public Page<Produit> getProduitss(String mc,int page)
{
return produitRepository.produitmc(mc, new PageRequest(page, 5) );**
}
and this my Dao layer using JpaRepository
package cat.dao;
import java.awt.print.Pageable;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import cat.entities.Produit;
public interface ProduitRepository extends JpaRepository<Produit, Long> {
// recuperé par mot clé
#Query("select p from produit as p where p.ref like x ")
public Page<Produit> produitmc (#Param("x")Long mc, Pageable p);
public List<Produit> findByRef (Long ref);
public List<Produit> findByRef (Long ref, Pageable p);
}
the function produitmc is suppose to make me search in entity produit by Ref the Erorr is in the function in controller (Bold) and it says
Description Resource Path Location Type
The method produitmc(Long, Pageable) in the type ProduitRepository is not applicable for the arguments (String, PageRequest) ProduitController.java /Mycatalogue/src/main/java/cat/Controller line 45 Java Problem
Yes.... Seems your argument passed doesn't match datatype expected. Else it should work.

Spring MockMvc redirectedUrl with pattern

I have a simple PersonController class that provides save() method to persist the object from http post request.
package org.rw.controller;
import java.sql.Timestamp;
import java.util.List;
import org.rw.entity.Person;
import org.rw.service.PersonService;
import org.rw.spring.propertyeditor.TimestampPropertyEditor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
#RequestMapping(value="/person")
public class PersonController {
private static final Logger logger = LoggerFactory.getLogger(PersonController.class);
#Autowired
private PersonService personService;
#Autowired
TimestampPropertyEditor timestampPropertyEditor;
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Timestamp.class, "dob", timestampPropertyEditor);
}
#RequestMapping(value="/save", method=RequestMethod.POST)
public String save(Model model, Person person) {
Long personId = personService.save(person);
return "redirect:view/" + personId;
}
}
As the save() method returns as return "redirect:view/" + personId;. It will be diffrerent for every request. it may be like "view/5" or "view/6" depending on the id of the object that has been persisted.
Then i have a simple class to test the above controller with spring mocking.
package org.rw.controller;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Test;
import org.rw.service.UserService;
import org.rw.test.SpringControllerTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
public class PersonControllerTest extends SpringControllerTest {
#Autowired
private UserService userService;
#Test
public void add() throws Exception {
mockMvc.perform(get("/person/add", new Object[0])).andExpect(status().isOk());
}
#Test
public void save() throws Exception {
UserDetails userDetails = userService.findByUsername("anil");
Authentication authToken = new UsernamePasswordAuthenticationToken (userDetails.getUsername(), userDetails.getPassword(), userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authToken);
mockMvc.perform(
post("/person/save", new Object[0])
.param("firstName", "JunitFN")
.param("lastName", "JunitLN")
.param("gender", "M")
.param("dob", "11/02/1989")
).andExpect(
redirectedUrl("view")
);
}
}
now here i have a problem that redirectedUrl("view") is rejecting value "view/5". I have tried redirectedUrl("view*") and redirectedUrl("view/*") but its not working.
Edit :
Here I have got a workaround as per below
MvcResult result = mockMvc.perform(
post("/person/save", new Object[0])
.param("firstName", "JunitFN")
.param("lastName", "JunitLN")
.param("gender", "MALE")
.param("dob", "11/02/1989")
).andExpect(
//redirectedUrl("view")
status().isMovedTemporarily()
).andReturn();
MockHttpServletResponse response = result.getResponse();
String location = response.getHeader("Location");
Pattern pattern = Pattern.compile("\\Aview/[0-9]+\\z");
assertTrue(pattern.matcher(location).find());
but still i am looking for the proper way.
update:
I have posted the same issue on spring jira here :
Since spring 4.0 you can use redirectedUrlPattern as pointed by Paulius Matulionis
As of spring 3.x this is not supported out of the box but you can easily add you custom result matcher
private static ResultMatcher redirectedUrlPattern(final String expectedUrlPattern) {
return new ResultMatcher() {
public void match(MvcResult result) {
Pattern pattern = Pattern.compile("\\A" + expectedUrlPattern + "\\z");
assertTrue(pattern.matcher(result.getResponse().getRedirectedUrl()).find());
}
};
}
And use it like build-in matcher
mockMvc.perform(
post("/person/save", new Object[0])
.param("firstName", "JunitFN")
.param("lastName", "JunitLN")
.param("gender", "M")
.param("dob", "11/02/1989")
).andExpect(
redirectedUrlPattern("view/[0-9]+")
);
Since 4.0 it is available in Spring itself.
Please check here.

Categories

Resources