UnsatisfiedDependencyException error debug log when [start] SpringDataJpa related repository objects can not be injected

Recent technological point of madness tree, I heard that spring data jpa than mybatis convenient too, just my own complete set project iedu (spring cloud-based online education platform is) only in its infancy (only good design tables and entity classes), Next you need to design a single sign-on system, so I'm just going to use spring data as a persistence framework.

Lu said everything should start with Hello World to write on, so I first wrote a demo:

(The following login code Service iedu-user-sso in a single point)

/**仓库类 - UserRepository
 * Spring Data JPA的基础使用,不解释。
*/

package cn.shadl.ieduusersso.repository;

import cn.shadl.ieducommonbeans.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
}
/**
 * 启动类兼测试类(因为只是个demo懒得专门写一个测试类所以就直接在启动类搞啦~)
 */

package cn.shadl.ieduusersso;

import cn.shadl.ieducommonbeans.domain.User;
import cn.shadl.ieduusersso.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@SpringBootApplication
@RestController

public class IeduUserSsoApplication {

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

    @Autowired
    private UserRepository userRepository;

    @RequestMapping("/")
    public String test(){
        List<User> users = userRepository.findAll();
        for(User user:users){
            System.out.println(user);
        }
        return "user list is displayed in console.";
    }
}

Results: failed to start

Key Information:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'ieduUserSsoApplication': Unsatisfied dependency expressed through field 'userRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class cn.shadl.ieducommonbeans.domain.User

Translation adults, then this information is reported to the effect UnsatisfiedDependencyException: application class failed to start because they can not inject objects based on "userRepository" this name.

Be able to read the error message, then debug it simple half. According to this basic information can be targeted to that question is @AutoWired annotated modified userRepository member variables there. Due to previously learned ssm, so I was a little prejudiced to think to write a UserRepository implementation class, and then built a package impl write UserRepositoryImpl.java. . . Read, read suddenly felt wrong ah? ? If I regard the interfaces in these methods to achieve the JpaRepository that this interface did what? ? So determined to write 10% of the package and its implementation class deleted, this time I already know this repository interface injection to give examples of objects certainly do not need to write your own (of course, is to use the Spring Data provided by friends), but since there are examples of good spring in mind for me, why would userRepository autowired failure? Through the Internet search and found a lot of people have plagued this problem fail trained repository objects injection, the case are the following:

1. User A, this man to write their own repository like added @Repository comment (inherited interface is not need to add repository jpa annotations, plus two equals repeat injection of bean, will throw an exception when the project started NoUniqueBeanDefinitionException )

2. User B, being given information about the type of bean is to say the required injection is not found, his solution is to start classes with the @EnableJpaRepositories ( "com.example.repository") comment

3. User C, the case of the man is a custom repository class inheritance is not specified when JpaRepository generic interfaces (XxxRepository extends JpaRepository <T, ID>, this person did not write <xx, xx>)

4. User Ding, who also wrote a demo, unit test results repeatedly measured repeatedly error. The original is because he is simply not the kind of repository within the test range to start scanning the class, the default scan configuration springboot is to scan the application to start classes at the same level or lower package

I and the above four conditions are different, there is no increase @Repository notes lead to ambiguity, the compiler can not find the type of bean did not say, do not forget to specify generic, repository class is also within the scanning range of application classes, which at first glance top four friends made a mistake I did not commit, but! ! ! I then react I program the wrong place, the situation is the situation users + C's friends Ding.


Not guessing, the problem is really out here:

public interface UserRepository extends JpaRepository<User, Long> {}

I did not forget to specify generic, but why is because the problem here and the bean can not find it?

See UserRepository warehouse source category is given at the beginning of the article, note that this User is another service introduced in coming:

import cn.shadl.ieducommonbeans.domain.User

Because it is spring cloud project, according to the design specifications micro-services project, I will generic entity classes are written in a iedu-common-beans this service inside, but here the use of spring data jpa is a single sign-on service iedu-user-sso , so the User is not natural in the default scan range sso service starts in the class.

Solution:

The User Services in writing sso

……

Lie to you, so you can solve the problem, but does not meet the original intention of the design of micro-services

Correct answer is to start scanning range defined sso service class, override the default configuration. Since I am here to share a common prefix common services and package name sso services "cn.shadl", so I just @SpringBootApplication annotation parameters modified to:

@SpringBootApplication(scanBasePackages = {"cn.shadl"})

If you want to scan to scan across projects but the projects are not common prefix, you can write:

@SpringBootApplication(scanBasePackages = {"com.example.A(这个服务自己所在的包)" , "cn.exp2.B(另一个服务里的包)"})

After modification, file application program can scan to another entity in the User class, "the extends JpaRepository UserRepository <User, Long> " recognition is successful, a successful example of the interface and the UserRepository userRepository the reference point to the object.


Incidentally, the name of the rest of the class name exactly the same reason can be variable spring automatic identification in addition to the first letter lowercase, because the spring container is essentially a Map: key for the variable name, value, compared with the bean instance, when when the programmer does not specify a specific key, key default is the class name first letter lowercase turn. Like @component and its derived classes (@ Controller, @ Service, @ Repository, etc.) If no value is specified, then the default key is to turn the class name first letter lowercase, if the custom value such as the value @Component ( "myBean") Thus, It will have a variable named myBean reference to autowired to this bean (this is a digression, spring Fundamentals)

发布了3 篇原创文章 · 获赞 0 · 访问量 54

Guess you like

Origin blog.csdn.net/Shadow___L/article/details/104070724