Jacket
Jacket

Reputation: 393

Spring-data : Error creating bean with name 'mainController': Unsatisfied dependency expressed through field 'userService'

I am new to spring-boot, when i try to run the mvn clean install the terminal gives me this ERROR:

[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 7.465 s <<< FAILURE! - in com.example.accessingdatamysql.AccessingDataMySqlApplicationTests
[ERROR] contextLoads  Time elapsed: 0.001 s  <<< ERROR!
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mainController': Unsatisfied dependency expressed through field 'userService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userServiceImpl': Unsatisfied dependency expressed through field 'mapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.accessingdatamysql.util.UserMapper' 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 'userServiceImpl': Unsatisfied dependency expressed through field 'mapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.accessingdatamysql.util.UserMapper' 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 'com.example.accessingdatamysql.util.UserMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

[INFO]
[INFO] Results:
[INFO]
[ERROR] Errors:
[ERROR]   AccessingDataMySqlApplicationTests.contextLoads » IllegalState Failed to load ...
[INFO]
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  13.677 s
[INFO] Finished at: 2020-10-03T22:37:51+02:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.22.2:test (default-test) on project accessingdatamysql: There are test failures.

I tried them all a bit but I can't get it started correctly, I've been stuck in this state for several days I add the various parts of the project AccessingDataMysqlApplication.java

package com.example.accessingdatamysql;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;


@SpringBootApplication
public class AccessingDataMysqlApplication {

  public static void main(String[] args) {
    SpringApplication.run(AccessingDataMysqlApplication.class, args);
  }

}

MainController.java

package com.example.accessingdatamysql.rest;





import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.example.accessingdatamysql.model.dto.UserDto;
import com.example.accessingdatamysql.service.UserService;


@RestController
public class MainController {
    
@Autowired 
private UserService userService;

  @Transactional
  @PostMapping(path="/demo/add")
  public @ResponseBody String addNewUser (@RequestParam String name
      , @RequestParam String email,@RequestParam String surname) 
  {
 

    UserDto n = new UserDto();
    n.setName(name);
    n.setSurname(surname);
    n.setEmail(email);
    userService.create(n);
    return "Saved";
  }



 


  @GetMapping("/demo/first")
  public UserDto one(@RequestParam String name) {
   System.out.print(name);
  return userService.findFirstByName(name); 
  }
}

UserService.java

package com.example.accessingdatamysql.service;

import org.springframework.stereotype.Service;

import com.example.accessingdatamysql.model.dto.UserDto;

@Service
public interface UserService {

    UserDto findFirstByName(String name);
    
    void create(UserDto user);
        
}
  

UserServiceImpl.java

package com.example.accessingdatamysql.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.accessingdatamysql.model.dto.UserDto;
import com.example.accessingdatamysql.model.entity.UserEntity;
import com.example.accessingdatamysql.model.repo.UserRepository;
import com.example.accessingdatamysql.util.UserMapper;

@Service
public class UserServiceImpl implements UserService{
    
    @Autowired
      private UserRepository userRepository;
    
    @Autowired
    UserMapper mapper;

    @Override
    public UserDto findFirstByName(String name) {
           UserEntity entity = userRepository.findFirstByName(name);
           
        return mapper.toDtoMapper(entity);
    }

    @Override
    public void create(UserDto user) {
         UserEntity entity = mapper.toEntityMapper(user);
         
         userRepository.create(entity);
        
    }
 
}

POM

<?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.3.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>accessingdatamysql</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>project</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
            </properties>

    <dependencies>
            <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>1.3.1.Final</version>
        </dependency>
        <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>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

The structure of my project is this:

src->com->example->accessingdatamysql|----->model
                                     |----->repo
                                     |----->util
                                     |----->service
                                     |----->rest----->Main.Controller.java
                                     |----->AccessingDataMysqlApplication.java

UserMapper.java

package com.example.accessingdatamysql.util;

import org.mapstruct.Mapper;

import com.example.accessingdatamysql.model.dto.UserDto;
import com.example.accessingdatamysql.model.entity.UserEntity;


@Mapper (componentModel = "spring")
public interface UserMapper {

    UserEntity toEntityMapper (UserDto user);
    
    UserDto toDtoMapper (UserEntity userEntity);
}

I tried to make changes With the MainController, to change the Controller but there are no changes. Entering either @EntityScan or @Component didn't help me in any way

Upvotes: 2

Views: 3854

Answers (2)

Shawrup
Shawrup

Reputation: 2734

I found the problem in UserService. UserService uses UserMapper interface but UserMapper is not a Spring managed bean. So @Autowired annotation does not work with UserMapper. Remove @Autowired from UserMapper and use UserMapper following MapStruct guidelines and the problem should be solved.

Your code should look like this. In UserService.java

UserMapper userMapper = Mappers.getMapper( UserMapper.class );

I also found that you missed maven plugin for mapstruct. You need to add this plugin for mapstruct to work. Your plugins section in pom.xml should look like this.

<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>
            <version>3.5.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>1.3.1.Final</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>

Hope this helps. For further information you can look at
https://mapstruct.org/
https://www.baeldung.com/mapstruct

Upvotes: 1

Ali
Ali

Reputation: 426

The issue is that spring is not able to create a bean of this type: com.example.accessingdatamysql.util.UserMapper It claims that there are no implementations of it. Check your annotations on that class.

Upvotes: 1

Related Questions