Проблема с аннотацией SpringBoot @Service

#java #spring #spring-boot #hibernate #jpa

Вопрос:

Привет, люди, я работаю над одним приложением .Я создал модель, но после предоставления всех аннотаций и настройки всех свойств она показывает ошибку ниже. Может ли кто-нибудь, пожалуйста, разобраться в приведенной ниже проблеме? применение.свойства

 spring.datasource.url = jdbc:mysql://localhost:3306/expenses
spring.datasource.username =dante
spring.datasource.password =jboss
spring.jpa.hibernate.ddl-auto=create
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
spring.jpa.open-in-view=false
spring.jpa.properties.hibernate.format_sql=true
server.port=9191

 

Основной Класс

 package com.expenses.demo;

import java.util.HashSet;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.expenses.demo.modal.Role;
import com.expenses.demo.modal.User;
import com.expenses.demo.modal.UserRole;
import com.expenses.service.UserService;

@SpringBootApplication
public class ExpenseApplication implements CommandLineRunner {
    
    @Autowired
    private UserService userService;
    
    public static void main(String[] args) {
        SpringApplication.run(ExpenseApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        System.out.println("Starting code");
        
        User user = new User();
        user.setFirstname("Aniket");
        user.setLastname("Turiley");
        user.setEmail("abc@gmail.com");
        user.setPassword("abc");
        user.setPhone("99220289");
        
        Role role1=new Role();
        role1.setRoleId(44L);
        role1.setRoleName("ADMIN");
        
        Set<UserRole> userRoleSet = new HashSet<>();
        UserRole userRole = new UserRole();
        userRole.setRole(role1);
        userRole.setUser(user);
        userRoleSet.add(userRole);
        
        User user1= this.userService.createUser(user,userRoleSet);
        System.out.println(user1.getUsername());
        
        
        
    }

}

 

Класс Модели

Role.java

 package com.expenses.demo.modal;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name="roleinformation")
public class Role {
    @Id
    private long roleId;
    private String roleName;
    
    @OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY,mappedBy = "role")
    private Set<UserRole> userRoles = new HashSet<>();
    public Role() {
    
    }
    
    
    public Role(int roleId, String roleName) {
        
        this.roleId = roleId;
        this.roleName = roleName;
    }
    public long getRoleId() {
        return roleId;
    }
    public void setRoleId(long l) {
        this.roleId = l;
    }
    public String getRoleName() {
        return roleName;
    }
    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }


    public Set<UserRole> getUserRoles() {
        return userRoles;
    }


    public void setUserRoles(Set<UserRole> userRoles) {
        this.userRoles = userRoles;
    }
    
    

}

 

User.java

 package com.expenses.demo.modal;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonIgnore;

@Entity
@Table(name="usersinfo")

public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private  Long id;
    private String firstname;
    private String lastname;
    private String username;
    private String password;
    private String email;
    private String phone;
    private boolean enable=true;
    
    // user has many roles
    @OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER,mappedBy = "user")
    @JsonIgnore
    private Set<UserRole> userRoles = new HashSet<>();
    
    public User() {
        
    }
    
    
    
    public User(Long id, String firstname, String lastname, String username, String password, String email,
            String phone, boolean enable) {
        
        this.id = id;
        this.firstname = firstname;
        this.lastname = lastname;
        this.username = username;
        this.password = password;
        this.email = email;
        this.phone = phone;
        this.enable = enable;
    }



    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getFirstname() {
        return firstname;
    }
    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }
    public String getLastname() {
        return lastname;
    }
    public void setLastname(String lastname) {
        this.lastname = lastname;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public boolean isEnable() {
        return enable;
    }
    public void setEnable(boolean enable) {
        this.enable = enable;
    }



    public Set<UserRole> getUserRoles() {
        return userRoles;
    }



    public void setUserRoles(Set<UserRole> userRoles) {
        this.userRoles = userRoles;
    }
    
    
    

}

 

Repository Interfaces

RoleRepository

 package com.expenses.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.expenses.demo.modal.Role;

public interface RoleRepository extends JpaRepository<Role, Long>{

}


 

UserRepository

 package com.expenses.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.expenses.demo.modal.User;

public interface UserRepository extends JpaRepository<User, Long> {

    public User findByUsername(String username);

}

 

Service Class

Service.java

 package com.expenses.service;

import java.util.Set;


import com.expenses.demo.modal.User;
import com.expenses.demo.modal.UserRole;

public interface UserService {
    
    //creating user
    public User createUser(User user,Set<UserRole> userRoles) throws Exception;
    

}

 

Service Implementation class

ServiceImplementation.java

 package com.expenses.service;

import java.util.Set;

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

import com.expenses.demo.modal.User;
import com.expenses.demo.modal.UserRole;
import com.expenses.repository.RoleRepository;
import com.expenses.repository.UserRepository;
import com.expenses.service.UserService;

@Service
public class UserServiceImplementation implements UserService{
    
    
    private UserRepository userRepository;
    
    @Autowired
    private RoleRepository roleRepository;
    
    
    @Override
    public User createUser(User user, Set<UserRole> userRoles) throws Exception{
         
        User local= this.userRepository.findByUsername(user.getUsername());
        if(local!=null) {
            System.out.println("User Already Exist");
            throw new Exception("User Already Exist");
        }else {
            // user create
            for(UserRole ur:userRoles) {
                roleRepository.save(ur.getRole());
            }
            user.getUserRoles().addAll(userRoles);
            local = this.userRepository.save(user);
        }
        return local;
    }

}


 

ошибка

 Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
[2m2021-07-28 18:16:59.304[0;39m [31mERROR[0;39m [35m8492[0;39m [2m---[0;39m [2m[  restartedMain][0;39m [36mo.s.b.d.LoggingFailureAnalysisReporter  [0;39m [2m:[0;39m 

***************************
APPLICATION FAILED TO START
***************************

Description:

Field userService in com.expenses.demo.ExpenseApplication required a bean of type 'com.expenses.service.UserService' 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 'com.expenses.service.UserService' in your configuration.


 

Комментарии:

1. Двигай своим ExpenseApplication com.expenses «куда».

2. package com.expenses.service не находится в пути сканирования компонента

Ответ №1:

Spring Boot выполнит сканирование компонентов (поиск классов с @Service , @Repository , @Controller , @Component ) только для классов с аннотациями, которые находятся в том же пакете, что и основной класс ( @SpringBootApplication класс с аннотациями), и его подпакеты.

Так что вам нужно восемь, чтобы

  • переместите ExpenseApplication один пакет вверх, чтобы com.expenses ,
  • переместите все классы, которые необходимо найти при сканировании компонентов, в в com.expenses.demo или в подпакет, или
  • настройте сканирование компонентов (и данные Spring тоже), например, с помощью @SpringBootApplication(scanBasePackages = "com.expenses")

Кстати: Наджиб Ариф тоже прав, кроме того, вам нужно добавить @Autowired UserServiceImplementation.userRepository , но я думаю, что вам не нужно добавлять @Repository аннотации к интерфейсам репозитория Spring-Data-JPA.

Комментарии:

1. Да, я понимаю, что объяснение исправлено, и теперь оно работает должным образом.

Ответ №2:

Добавьте это в свой основной класс

 @SpringBootApplication(scanBasePackages = "com.expenses")
 

Это поможет компоненту сканирования найти ваши классы.

Ответ №3:

Сначала отметьте оба ваших репозитория

 @Repository
 

В вашем пользовательском сервисе отсутствует аннотация с автоматической проводкой.

Мне лично нравится инъекция конструктора.

Хранилище ролей

     @Repository
    public interface RoleRepository extends JpaRepository<Role, Long>{
    }
 

То же самое касается пользовательского репо.

в вашем Пользовательском сервисе Impl

 @Service
public class UserServiceImplementation implements UserService{
    
    
    private final UserRepository userRepository;
    private final RoleRepository roleRepository;

    /* when using constructor injection @Autowired is not required */
    public UserServiceImplementation(UserRepository userRepository, RoleRepository roleRepository){
       this.userRepository = userRepository;
       this.roleRepository = roleRepository;
    }

    @Override
    public User createUser(User user, Set<UserRole> userRoles) throws Exception{
        //...
    }

}
 

Комментарии:

1. Я не думаю, что нужно комментировать интерфейсы репозитория Spring-Data-JPA @Repository , я думаю, что extends <Spring-Data-Interface> это достаточно

2. В любом случае, вы правы с отсутствующей аннотацией @Autowired (или инъекцией C-tor)

3. Да, я обновил класс ServiceImplementation в соответствии с вашим предложением, и он работает . Я понял ошибку и исправил ее . Спасибо, Наджиб.