Spring Boot Pagination returning null array - spring

Trying my hands at Spring Boot Pagination. But the resulting array is empty.
Controller:
package mypackage;
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.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class Controller {
#Autowired
CustomerRepository customerRepository;
#GetMapping(value="/get/customers/{page}")
public List<Customers> getCustomersPaginated(#PathVariable("page") int page)
{
Pageable pageableObject=PageRequest.of(page, 2, Sort.by("cnum").ascending());
Page<Customers> pageObject = customerRepository.findAll(pageableObject);
return pageObject.getContent();
}
}
CustomerRepository:
package mypackage;
import org.springframework.data.jpa.repository.JpaRepository;
public interface CustomerRepository extends JpaRepository<Customers, Integer> {
}
Customers:
package mypackage;
import javax.persistence.Entity;
import javax.persistence.Id;
import lombok.Data;
import lombok.RequiredArgsConstructor;
#Entity//(name = "customers")
#Data
#RequiredArgsConstructor
public class Customers {
#Id
int cnum;
int rating,snum;
String cname, city;
}
Customers Table schema:
mysql> desc customers;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| cnum | int | NO | PRI | NULL | |
| cname | varchar(20) | NO | | NULL | |
| city | varchar(20) | NO | | NULL | |
| rating | int | NO | | NULL | |
| snum | int | YES | MUL | NULL | |
+--------+-------------+------+-----+---------+-------+
But the resulting array is empty, as shown in the following screenshot:
What do you think is the problem? It knows that I am requesting 2 results per page, but it is sending an array of null records. What am I missing here?
Edit 1: Eclipse logs. Why is it firing a query for count?
Edit 2:
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>SpringPagination</groupId>
<artifactId>SpringPagination</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>17</release>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
</plugin>
</plugins>
</build>
</project>

the query you are getting in logs , in the end there is limit ?,? which looks incorrect it should be limit ? offset ? when you are passing value of page other than 0
as for count query it gets executed when you don't have offset but since you are passing 1 for page than there should be offset and count query should not get executed , can you share you pom.xml need to check the version of dependencies you are using

Pagination starts zero. Make sure you have enough rows. If there is any row, send page 0 and check if something is coming.
You can try:
PageRequest.of(0, 2);
or
For more detailed information on how to paginate, you can review.

As posted by #Anurag Negi, I checked his repo link.
THE ONLY CHANGE I DID WAS REMOVING THE #Data and #RequiredArgsConstructor annotations and adding manually all the setters and getters and constructors. And it worked flawlessly.
Looks like there is an issue with lombok annotations.

Related

New H2 version breaks liquibase

New version of H2 seems to have broken liquibase and JPA
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.h2test</groupId>
<artifactId>h2test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>h2test</name>
<description>h2test</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.6.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>4.7.1</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.210</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.properties
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
classes:
package com.h2test.h2test.domain;
import lombok.Data;
import javax.persistence.*;
#Entity
#Data
public class Person {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column
private String firstName;
#Column
private String lastName;
}
package com.h2test.h2test.repository;
import com.h2test.h2test.domain.Person;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface PersonRepository extends JpaRepository<Person, Long> {
}
#RestController
public class SomethingController {
#Autowired
private PersonRepository personRepository;
#GetMapping
public String test() {
Person person = new Person();
person.setFirstName("first name");
person.setLastName("last name");
personRepository.save(person);
return "hello";
}
}
Liquibase file:
databaseChangeLog:
- changeSet:
id: createTable-example
author: liquibase-docs
changes:
- createTable:
tableName: person
columns:
- column:
name: id
type: int
autoIncrement: true
constraints:
primaryKey: true
nullable: false
- column:
name: first_name
type: varchar(50)
- column:
name: last_name
type: varchar(50)
constraints:
nullable: false
When triggering the REST ENDPOINT localhost:8080 that creates and saves the Person entity I get the following error:
org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: NULL not allowed for column "ID"; SQL statement:
insert into person (id, first_name, last_name) values (null, ?, ?) [23502-202]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:508) ~[h2-2.0.202.jar:2.0.202]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477) ~[h2-2.0.202.jar:2.0.202]
This seems to only happen in the newer versions of H2. Any help is appreciated
Version 2.6.3 of spring-boot-starter-data-jpa has org.hibernate:hibernate-core:5.6.4.Final in its dependencies. This version doesn't support H2 2.x.y. You need to use 5.6.5:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.6.5.Final</version>
</dependency>
Also something is wrong with your classpath. You have H2 2.1.210 in dependencies, but exception in your question has error code 23502-202, it means it was produced by H2 2.0.202, you shouldn't use this outdated version, Hibernate ORM may have some problems with it.

Java Bean Validation API’s #Valid not working (Spring in action)

I am following the book "Spring in Action, 5th Edition". Currently on Chapter 2 where validation is being applied to the forms. I have followed the exact same steps in the book but, but my forms don't recognize that there are any errors.
OrderFromController.java
Using Java Bean Validation API’s #Valid on the Order object being passed into the processOrder method
package com.example.tacocloud.contoller;
import com.example.tacocloud.dto.Order;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import lombok.extern.slf4j.Slf4j;
import javax.validation.Valid;
#Slf4j
#Controller
#RequestMapping("/orders")
public class OrderController {
#GetMapping("/current")
public String orderForm(Model model) {
model.addAttribute("order", new Order());
return "orderForm";
}
#PostMapping
public String processOrder(#Valid Order order, Errors errors) {
if(errors.hasErrors()){
log.info("Handling errors");
return "orderForm";
}
log.info("Order submitted: " + order);
return "redirect:/";
}
}
OrderObject.java
Object on which validation should be performed
package com.example.tacocloud.dto;
import lombok.Data;
import org.hibernate.validator.constraints.CreditCardNumber;
import javax.validation.constraints.Digits;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
#Data
public class Order {
#NotBlank(message = "Name is required!")
private String name;
#NotBlank(message="Street is required")
private String street;
#NotBlank(message="City is required")
private String city;
#NotBlank(message="State is required")
private String state;
#NotBlank(message="Zip code is required")
private String zip;
#CreditCardNumber(message = "Not a valid credit card number")
private String ccNumber;
#Pattern(regexp="^(0[1-9]|1[0-2])([\\/])([1-9][0-9])$",
message="Must be formatted MM/YY")
private String ccExpiration;
#Digits(integer=3, fraction=0, message="Invalid CVV")
private String ccCVV;
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>taco-cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>taco-cloud</name>
<description>Example from Spring in Action 5th Edition</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>7.0.1.Final</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

My rest controller is not get called from URL

My Rest Controller is not getting called. Can you kindly guide me?
I have created an API for bus reservation scenario for that my controller is not getting called.
Is there any issue in configuration?
I have tried by using following URL:
http://localhost:9090/service/api/bus/enter link description here
debug breakpoint is also not coming.
import org.slf4j.Logger;
import java.sql.Date;
import java.util.List;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.ApiOperation;
#RestController
#RequestMapping(value = "/service")
public class ServiceController {
#Autowired
private ComponentDetailsService busService;
#ApiOperation("This is the hello world api")
#GetMapping("/api/bus/")
public String hello() {
ComponentDetailsEntity bus = new ComponentDetailsEntity();
bus.setArrivalTime("10");
bus.setBusNumber("TN11");
bus.setDepature("salem");
bus.setDestinationCity("chennai");
bus.setDuration("5");
bus.setOperatorName("bala");
bus.setPrice(350);
bus.setReturnDate(Date.valueOf("2020-5-4"));
bus.setSourceCity("Salem");
bus.setTravelDate(Date.valueOf("2020-5-3"));
busService.postBus(bus);
System.out.println("a");
return "hello";
}
#GetMapping("/api/bus/{sourceCity}/{destinationCity}/{travelDate}")
public List<ComponentDetailsEntity> findAll(#PathVariable("sourceCity") String sourceCity, #PathVariable("destinationCity") String destinationCity,
#PathVariable("travelDate") String strdate) {
Date date = Date.valueOf(strdate);
return busService.findAll(sourceCity,destinationCity,date);
}
}
server.port=9090
spring.datasource.url=jdbc:h2:mem:db
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=h2
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.h2.console.enabled=true
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.codejudge</groupId>
<artifactId>sb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sb</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<swagger.version>2.4.0</swagger.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springf
ramework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
</dependencies>
<build>
<finalName>spring-boot-in-docker</finalName>
<plugins>
<!-- This is needed if deploying with embedded server -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Please check your console output, e.g. if there is any exception in your service class. The code you provided does work and generates the output "hello".

I can't add mapstruct in my Spring project

I try to add mapstruct mapper in my Spring project.
I have a User entity. I need to show a list of users in the admin panel. For this, I did DTO UserForAdmin, mapper UserMapper and rest controller AdminRestController. When I try to get UserMapper I get errors.
I try two ways:
Mappers.getMapper(UserMapper.class)
I get error
java.lang.ClassNotFoundException: Cannot find implementation for
ru.project.mapper.UserMapper
Autowired
I get error
Error starting ApplicationContext. To display the conditions report
re-run your application with 'debug' enabled. 2019-07-17 15:47:07.886
ERROR 13652 --- [ restartedMain]
o.s.b.d.LoggingFailureAnalysisReporter :
*************************** APPLICATION FAILED TO START
Description:
Field userMapper in ru.project.controller.rest.AdminRestController
required a bean of type 'ru.project.mapper.UserMapper' that could not
be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'ru.project.mapper.UserMapper' in
your configuration.
Here my source code.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>ru.project</groupId>
<artifactId>project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>project</name>
<description>The project is project of resourse for investors.</description>
<properties>
<java.version>12</java.version>
<org.mapstruct.version>1.3.0.Final</org.mapstruct.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.3.5</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>
My interface UserMapper:
package ru.project.mapper;
import java.util.List;
import org.mapstruct.Mapper;
import ru.project.domain.User;
import ru.project.dto.UserForAdmin;
#Mapper
//#Mapper(componentModel = "spring")
public interface UserMapper {
UserForAdmin UserToUserForAdmin(User user);
List<UserForAdmin> UserListToUserForAdminList(List<User> user);
}
My RestController:
package ru.project.controller.rest;
import java.util.List;
import org.mapstruct.factory.Mappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import ru.project.dto.UserForAdmin;
import ru.project.mapper.UserMapper;
import ru.project.service.UserService;
#RestController
public class AdminRestController {
#Autowired
private UserService userService;
//#Autowired
//private UserMapper userMapper;
#GetMapping("/admin/users")
public List<UserForAdmin> findAllUsers(){
UserMapper userMapper = Mappers.getMapper(UserMapper.class);
return userMapper.UserListToUserForAdminList(userService.findAll());
}
}
I would like to use Awtowired.
You need to use #Mapper(componentModel="spring")
package ru.project.mapper;
import java.util.List;
import org.mapstruct.Mapper;
import ru.project.domain.User;
import ru.project.dto.UserForAdmin;
#Mapper(componentModel = "spring")
public interface UserMapper {
UserForAdmin UserToUserForAdmin(User user);
List<UserForAdmin> UserListToUserForAdminList(List<User> user);
}
and use below in AdminRestController
#Autowired
private UserMapper userMapper;
And i am assuming that User and UserForAdmin have same field names
After this run mvn clean compile and sources will be generated
An alternative answer to using annotation #Mapper(componentModel = "spring") would be to add the component model as compiler arguments in the plugin. The annotation works but the annoying thing may be having to add it to every mapper you create. A compiler argument you add once and works for all mappers in the project. Below is an example of a plugin definition with the componentModel compiler argument.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<arg>-Amapstruct.defaultComponentModel=spring</arg>
</compilerArgs>
</configuration>
</plugin>
I have tried this with versions 1.3.0.Final as well as 1.3.1.Final and sping boot 2.1.7/8/9
Use #Mapper(componentModel = "spring") - enable di.
Run mvn package command -it creates the implementation class.
#Autowired the mapper interface and use.
(method name start letter in java should be lower case)
There is one simple solution.
at your mapper class, use #Mapper(componentModel = "spring")
and the run mvn clean install command from terminal.
or in case of STS/ Eclipse, go to Project> Run As> maven clean
and then run Project> Run As> maven install
and your mapper Impl will be generated!
NOTE: Regarding to plugins
if you're using both of following dependencies then no need to use plugin in pom.xml file
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
and properties will be like;
<properties>
<java.version>11</java.version>
<org.mapstruct.version>1.3.1.Final</org.mapstruct.version>
</properties>
I solved it by adding scanBasePackages
#SpringBootApplication(scanBasePackages = {
"com.yourpackagepath.mapper"
})
Cannot find implementation for ru.project.mapper.UserMapper that means UserMapper must be implements by some class.
such as public Class UserMapperImple implements UserMapper {XXXXXXX}
then the Mappers.getMapper("UserMapper") will get UserMapperImple.
Consider defining a bean of type 'ru.project.mapper.UserMapper' in your configuration. that means #Mapper do not work; i advise you to check the spring-config.xml. may the ApplicationContext not scan this package.
hope to help you :)

You can implement missing steps with the snippets below

>## This my Pom.xml file structure ##
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cucumberExcecise</groupId>
<artifactId>Cucumber_Practice</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.7.0</version>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-java</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-jvm-deps</artifactId>
<version>1.0.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-junit</artifactId>
<version>1.2.5</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
## Feature File:##
Feature: Login Feature
Scenario: Login as a authenticated user
Given User is on Home Page
**Step Definition code:**
#Given("User is on Home Page$")
public void user_is_on_homepage() {
// Write code here that turns the phrase above into concrete actions
System.setProperty("webdriver.chrome.driver", "E:\\Downloads\\chromedriver_win32\\chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://sample.com");
}
**Runner Class:**
#RunWith(Cucumber.class)
#CucumberOptions(strict = true,features = "src/test/resources/featureFiles/sample.feature", glue = {
"src/test/java/com/stepDefinitions/Step.java" })
public class TestRunner {
}
**Whenever running Runner class its showing below error:**
1 Scenarios ([33m1 undefined[0m)
1 Steps ([33m1 undefined[0m)
0m0.000s
You can implement missing steps with the snippets below:
#Given("^User is on Home Page$")
public void user_is_on_Home_Page() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
in your Testrunner class you have to put some stuff, or rather it has certain annotations (the class itself is empty)
You have to tell where the Feature files are and where the steps files are (the .java files, this comes in the "glue")
You can also specify tags (then you annotate your features or scenarios with #something to run these )
And there are other options that deal with things like reports.
an example would be:
package steps;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
import org.junit.runner.RunWith;
#RunWith(Cucumber.class)
#CucumberOptions(features = "src/test/resources/"
, monochrome = false
, format = { "pretty", "html:target/results" }
, glue = { "steps" }
, strict = true
, tags = {"#RT-interact"}
)
public class TestRunner {
}
There are many tutorials such as http://www.automationtestinghub.com/cucumber-test-runner-class-junit/ where you can find more info.

Resources