I get this error when I run my Spring Boot application:
Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2024-05-11T14:59:30.328+04:00 ERROR 12628 --- [Assignment-3] [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 1 of constructor in az.edu.ada.wm2.Assignment3.service.impl.BookServiceImpl required a bean of type 'az.edu.ada.wm2.Assignment3.mapper.BookMapper' that could not be found.
Here are my source files:
Book.java
package az.edu.ada.wm2.Assignment3.model.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import jakarta.persistence.*;
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String author;
private String description;
private String publishYear;
}
BookDto.java
package az.edu.ada.wm2.Assignment3.model.dto;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BookDto {
private Long id;
@NotBlank(message = "Title is required")
@Size(max = 100, message = "Title must be less than 100 characters")
private String title;
@NotBlank(message = "Author is required")
@Size(max = 50, message = "Author must be less than 50 characters")
private String author;
@NotBlank(message = "Description is required")
@Size(max = 200, message = "Description must be less than 200 characters")
private String description;
}
BookServiceImpl.java
package az.edu.ada.wm2.Assignment3.service.impl;
import az.edu.ada.wm2.Assignment3.mapper.BookMapper;
import az.edu.ada.wm2.Assignment3.model.dto.BookDto;
import az.edu.ada.wm2.Assignment3.model.entity.Book;
import az.edu.ada.wm2.Assignment3.repository.BookRepository;
import az.edu.ada.wm2.Assignment3.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class BookServiceImpl implements BookService {
private final BookRepository bookRepository;
private final BookMapper bookMapper;
@Autowired
public BookServiceImpl(BookRepository bookRepository, BookMapper bookMapper){
this.bookRepository=bookRepository;
this.bookMapper = bookMapper;
}
@Override
public List<BookDto> getAllBooks() {
return bookRepository.findAll().stream()
.map(bookMapper::bookToBookDto)
.collect(Collectors.toList());
}
@Override
public BookDto getBookById(Long id) {
return bookMapper.bookToBookDto(bookRepository.findById(id)
.orElseThrow(() -> new RuntimeException("Book not found")));
}
@Override
public BookDto createBook(BookDto bookDTO) {
Book book = bookMapper.bookDtoToBook(bookDTO);
return bookMapper.bookToBookDto(bookRepository.save(book));
}
@Override
public BookDto updateBook(Long id, BookDto bookDTO) {
Book existingBook = bookRepository.findById(id)
.orElseThrow(() -> new RuntimeException("Book not found"));
existingBook.setTitle(bookDTO.getTitle());
existingBook.setAuthor(bookDTO.getAuthor());
existingBook.setDescription(bookDTO.getDescription());
return bookMapper.bookToBookDto(bookRepository.save(existingBook));
}
@Override
public void deleteBook(Long id) {
bookRepository.deleteById(id);
}
}
BookController.java
package az.edu.ada.wm2.Assignment3.controller;
import az.edu.ada.wm2.Assignment3.model.dto.BookDto;
import az.edu.ada.wm2.Assignment3.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
import java.util.List;
@RestController
@RequestMapping("/books")
public class BookController {
private final BookService bookService;
@Autowired
public BookController(BookService bookService) {
this.bookService = bookService;
}
@GetMapping
public ResponseEntity<List<BookDto>> getAllBooks() {
List<BookDto> books = bookService.getAllBooks();
return ResponseEntity.ok(books);
}
@GetMapping("/{id}")
public ResponseEntity<BookDto> getBookById(@PathVariable Long id) {
BookDto book = bookService.getBookById(id);
return ResponseEntity.ok(book);
}
@PostMapping
public ResponseEntity<BookDto> createBook(@Valid @RequestBody BookDto bookDTO) {
BookDto createdBook = bookService.createBook(bookDTO);
return ResponseEntity.status(HttpStatus.CREATED).body(createdBook);
}
@PutMapping("/{id}")
public ResponseEntity<BookDto> updateBook(@PathVariable Long id, @Valid @RequestBody BookDto bookDTO) {
BookDto updatedBook = bookService.updateBook(id, bookDTO);
return ResponseEntity.ok(updatedBook);
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteBook(@PathVariable Long id) {
bookService.deleteBook(id);
return ResponseEntity.noContent().build();
}
}
build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.5'
id 'io.spring.dependency-management' version '1.1.4'
}
group = 'az.edu.ada.wm2'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
implementation 'org.mapstruct:mapstruct:1.5.5.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
I tried using lombok for service class as suggested in most online solutions, however, that didn't help either. Could you please help me to find and fix the issue?
An error a bean of type 'az.edu.ada.wm2.Assignment3.mapper.BookMapper' that could not be found
means there is no such been known to Spring, that is no such bean in Spring context. There are many possible reasons of that, but in your case it is about BookMapper generated by mapstruct. You did not supply BookMapper code, but I suppose you missed annotation @Mapper(componentModel = "spring")
which makes mapper impl class to be a spring bean. See an example at https://www.baeldung.com/mapstruct