While using mapstruct dependency it gives 404 error for my endpoints in my console and whitelabel error in browser.
I'm trying to implement mapstruct in my webflux project with swagger-ui. Running my project without mapstruct dependency my controller endpoints are working perfectly. But when im using it, it gives 404 error in my console and whitelabel error in my browser. In Swagger the swagger ui page has been rendered but my test controller is not getting displayed.
Here, is my Code
<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>3.2.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>fluxDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>fluxDemo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>21</java.version>
<org.mapstruct.version>1.6.0.Beta1</org.mapstruct.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>r2dbc-postgresql</artifactId>
<version>1.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-r2dbc</artifactId>
<version>3.2.4</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webflux-ui</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.6.0.Beta1</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.mapstruct</groupId>-->
<!-- <artifactId>mapstruct-processor</artifactId>-->
<!-- <version>1.5.5 Final</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.projectlombok</groupId>-->
<!-- <artifactId>lombok-mapstruct-binding</artifactId>-->
<!-- <version>0.2.0</version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-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>
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-compiler-plugin</artifactId>-->
<!-- <version>3.11.0</version>-->
<!-- <configuration>-->
<!-- <source>11</source>-->
<!-- <target>11</target>-->
<!-- <annotationProcessorPaths>-->
<!-- -->
<!-- <path>-->
<!-- <groupId>org.mapstruct</groupId>-->
<!-- <artifactId>mapstruct-processor</artifactId>-->
<!-- <version>1.5.5.Final</version>-->
<!-- </path>-->
<!-- -->
<!-- </annotationProcessorPaths>-->
<!-- </configuration>-->
<!-- </plugin>-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>
Here, in this class when i remove @ComponentScan annotation and running it, it give me an error that bean Mapper is not found in the defined package.
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Info;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@OpenAPIDefinition(info = @Info(title = "testFlux", version = "0.0.1", description = "test project"))
@ComponentScan(basePackages = {"com.example.fluxDemo.Mapper"})
public class FluxDemoApplication {
public static void main(String[] args) {
SpringApplication.run(FluxDemoApplication.class, args);
}
}
package com.example.fluxDemo.Mapper;
import com.example.fluxDemo.Dto.TestModelDto;
import com.example.fluxDemo.Model.TestModel;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import org.springframework.stereotype.Component;
@Mapper
public interface TestMapper {
TestMapper INSTANCE = Mappers.getMapper(TestMapper.class);
TestModelDto entityToDto(TestModel testModel);
TestModel dtoToEntity(TestModelDto testModelDto);
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TestModelDto {
private Long id;
private String username;
private String address;
}
package com.example.fluxDemo.Model;
import org.springframework.data.annotation.Id;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.relational.core.mapping.Table;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Table("test_model_db")
public class TestModel {
@Id
private Long id;
private String username;
private String address;
}
ParentController class
package com.example.fluxDemo.Controller;
import com.example.fluxDemo.Dto.TestModelDto;
import com.example.fluxDemo.Service.ParentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@RestController
@RequestMapping("/test")
public class ParentController {
@Autowired
private ParentService service;
@GetMapping("/hello")
public ResponseEntity<Mono<String>> test(){
return ResponseEntity.ok().body(Mono.just("Hello..!"));
}
@GetMapping("/all")
public ResponseEntity<Flux<TestModelDto>> allModels(){
return ResponseEntity.ok().body(service.all());
}
@GetMapping("/{id}")
public ResponseEntity<Mono<TestModelDto>> getModel(@PathVariable Long id){
return ResponseEntity.ok().body(service.getModel(id));
}
@PostMapping("/new")
public ResponseEntity<Mono<TestModelDto>> newModel(@RequestBody Mono<TestModelDto> testModelDto){
return ResponseEntity.ok().body(service.saveModel(testModelDto));
}
@PutMapping("/update")
public ResponseEntity<Mono<TestModelDto>> updateModel(@RequestBody Mono<TestModelDto> testModelDtoMono,
Long id){
return ResponseEntity.accepted().body(service.updateModel(testModelDtoMono, id));
}
@DeleteMapping("/{id}")
public Mono<Void> deleteModel(@PathVariable Long id){
return service.deleteById(id);
}
}
Note: It works perfectly when i removed mapstruct dependency and all.
Can Anyone clarify??
In FluxDemoApplication
class try following, so controller classes will also get scanned.
@ComponentScan(basePackages = {"com.example.fluxDemo"})