spring-bootillegalstateexceptionmodelmapper

Spring Boot - Can't handle IllegalStateException


I am in the process of learning spring boot, however, I encountered a problem and I can not find a solution. When I try to run the test, I get the following exception.

java.lang.IllegalStateException: Failed to load ApplicationContext

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookServiceImplementation' defined in file []: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'uploadFileServiceImplementation' defined in file []: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.modelmapper.ModelMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'uploadFileServiceImplementation' defined in file []: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.modelmapper.ModelMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.modelmapper.ModelMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

I tried to put an annotation in different places, but it did not solve my problem. I completely don't know how should I create ModelMapper bean. Maybe you will know how to deal with it.

My Code

BookServiceImplementation.class

    @Service
    public class BookServiceImplementation implements BookService {
        private BookRepository bookRepository;
        private UploadFileService uploadFileService;
        private ModelMapper modelMapper;

        @Autowired
        public BookServiceImplementation(BookRepository bookRepository, UploadFileService uploadFileService,
                                     ModelMapper modelMapper){
            this.bookRepository = bookRepository;
            this.uploadFileService = uploadFileService;
            this.modelMapper = modelMapper;
        }

        @Override
        public void addBook(AddBookResource addBookResource) {
            Book book = new Book();
            Long coverImageId = addBookResource.getCoverImageId();
            Long contentId = addBookResource.getContentId();
            UploadFile coverImage = null;
            UploadFile bookContent = null;

            if (coverImage != null){
                coverImage = uploadFileService.findById(coverImageId)
                    .map(fileResource -> modelMapper.map(fileResource, UploadFile.class))
                    .orElse(null);
            }
            if (contentId != null){
            bookContent = uploadFileService.findById(contentId)
                    .map(fileResource -> modelMapper.map(fileResource, UploadFile.class))
                    .orElse(null);
            }

            book.setCoverImage(coverImage);
            book.setContent(bookContent);
            book.setTitle(addBookResource.getTitle());
            book.setDescription(addBookResource.getDescription());          
            book.setCategories(Arrays.stream(addBookResource.getCategories())
                .map(Category::new)
                .collect(Collectors.toSet()));

           bookRepository.save(book);
           }
    }

UploadFileServiceImplementation.class

    @Service
    public class UploadFileServiceImplementation implements UploadFileService {
        private UploadFileRepository uploadFileRepository;
        private ModelMapper modelMapper;

        @Autowired
        public UploadFileServiceImplementation(UploadFileRepository uploadFileRepository, ModelMapper modelMapper){
           this.uploadFileRepository = uploadFileRepository;
           this.modelMapper = modelMapper;
        }

        @Transactional
        @Override
        public Long save(String filename, byte[] data) {
            UploadFile uploadFile = new UploadFile();
            uploadFile.setFileName(filename);
            uploadFile.setData(data);

            UploadFile saved = uploadFileRepository.save(uploadFile);
            return saved.getId();
        }

        @Override
        public Optional<FileResource> findById(Long id) {
            return uploadFileRepository.findById(id)
                .map(file -> modelMapper.map(file, FileResource.class));
        }
    }

EDIT After a suggested changes I still got an IllegalStateException:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookService': Unsatisfied dependency expressed through field 'uploadFileService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'uploadFileService': Unsatisfied dependency expressed through field 'modelMapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.modelmapper.ModelMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'uploadFileService': Unsatisfied dependency expressed through field 'modelMapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.modelmapper.ModelMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.modelmapper.ModelMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Solution

  • Step 1: Add a @Bean for Model mapper if already not there in main application class or configuration class:

    @SpringBootApplication
    public class Application {
    public static void main(String[] args){
        SpringApplication.run(Application.class, args);
    }
    
    @Bean
    public ModelMapper modelMapper() {
        return new ModelMapper();
    }
    

    }

    Step 2: Here is how you can manage it, please make below chnages in service impl:

    @Service("uploadFileService")
    public class UploadFileServiceImplementation implements UploadFileService {
    
       @Autowired
       private UploadFileRepository uploadFileRepository;
    
       @Autowired
       private ModelMapper modelMapper;
    
      //Remove constructure now.
    

    same do for BookServiceImplementation

    @Service("bookService")
    public class BookServiceImplementation implements BookService {
    
       @Autowired
       private BookRepository bookRepository;
    
       @Autowired
       private UploadFileService uploadFileService;
    
       @Autowired
      private ModelMapper modelMapper;
    
    //remove constructure