繁体   English   中英

Spring 注入 JPA 存储库 bean 不工作 - NullPointerException

[英]Spring Injection of JPA Repository bean is not working - NullPointerException

我正在尝试将由 Spring 管理和实现的 JPA 存储库注入到服务 class 中。 但是在运行时程序在第 39 行抛出 NPE。

这是我的服务 class:

@Service
public class RegistrationFormProcessor {

    private ContractorRepository contractorRepository;
    private AddressRepository addressRepository;
    private UserRepository userRepository;
    private PasswordEncoder passwordEncoder;

    @Autowired
    public RegistrationFormProcessor(ContractorRepository contractorRepository, AddressRepository addressRepository, UserRepository userRepository, PasswordEncoder passwordEncoder) {
        this.contractorRepository = contractorRepository;
        this.addressRepository = addressRepository;
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
    }

    public User prepareUser(RegistrationForm registrationForm) {
        Address address = new Address(
                registrationForm.getCountry(),
                registrationForm.getCity(),
                registrationForm.getStreet(),
                registrationForm.getZipCode(),
                registrationForm.getProperty()
        );
        Address savedAddress = addressRepository.save(address); // line 39

        Contractor userCompany = new Contractor(
                registrationForm.getCompanyName(),
                registrationForm.getShortName(),
                savedAddress,
                registrationForm.getNip(),
                registrationForm.getRegon(),
                registrationForm.getPhone(),
                registrationForm.getEmail(),
                registrationForm.getWebsite()
        );
        Contractor savedUserCompany = contractorRepository.save(userCompany); // line 51

        User user = new User(
                registrationForm.getFirstName(),
                registrationForm.getLastName(),
                registrationForm.getLastName(),
                passwordEncoder.encode(registrationForm.getPassword()),
                "ROLE_USER",
                true,
                savedUserCompany
        );
        User savedUser = userRepository.save(user);

        savedUserCompany.setOwner(savedUser);
        contractorRepository.save(savedUserCompany);

        return savedUser;
    }

AddressRepository 和其他字段与由 Spring 管理的接口自动连接,该接口自动实现所有方法。

import org.springframework.data.repository.CrudRepository;

public interface AddressRepository extends CrudRepository <Address, Long> {}

就我而言,RegistrationFormProcessor 的实例是由 Spring 管理的实例(至少我希望如此)。 RegistrationFormProcessor 被注释@Service并被注入 controller class 之一。 在那里使用它并且程序抛出提到的异常。 在 controller 下方:

@Controller
@RequestMapping("/register")
public class RegistrationController {
    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    public RegistrationController(UserRepository userRepository, PasswordEncoder passwordEncoder) {
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
    }

    @GetMapping
    public String registerForm(Model model) {
        model.addAttribute("registrationForm", new RegistrationForm());
        return "register/registration";
    }

    @PostMapping
    public String processRegistrationForm(RegistrationForm form, @Autowired RegistrationFormProcessor registrationFormProcessor) {
        registrationFormProcessor.prepareUser(form);
        return "redirect:/login";
    }
}

如果删除第 39 行,程序将在第 51 行处理 NPE(如果userRepository.save(user) ,则依此类推)。 在这些行中,应该使用由 Spring-data 自动实现的save()等方法的存储库。

我在 controller 类中有类似的注入(也在构造函数中),并且一切正常。

我做错了什么? 为什么在服务中 class Spring 不注入这些依赖项和字段是 null? 我尝试设置断点并调试 - 确认字段为null 正如我上面所说的,在其他被注释为@Controller的类中,同样的字段也注入到构造函数中,它们不是空值,并且一切正常。

试图将接口 AddresRepository 注释为@Repository但它不起作用。 另一方面,对于 Spring - Spring 没有必要确保在控制器中正确实施方法。

提前感谢您的任何建议。

您可以删除 @Autowired 注释并将 final 关键字添加到存储库定义中,如下所示:

private final ContractorRepository contractorRepository;
private final AddressRepository addressRepository;
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;

public RegistrationFormProcessor(ContractorRepository contractorRepository, AddressRepository addressRepository, UserRepository userRepository, PasswordEncoder passwordEncoder) {
    this.contractorRepository = contractorRepository;
    this.addressRepository = addressRepository;
    this.userRepository = userRepository;
    this.passwordEncoder = passwordEncoder;
}

您应该尝试为您的存储库添加final关键字以进行注入,如下所示:

private final ContractorRepository contractorRepository;
private final AddressRepository addressRepository;
...

通过将 controller 中的 RegistrationFormProcessor 注入从 controller 方法中的注入作为参数声明为字段并在 controller 字段中注入来解决问题。

@Controller
@RequestMapping("/register")
public class RegistrationController {
    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    public RegistrationController(UserRepository userRepository, PasswordEncoder passwordEncoder) {
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
    }

    @PostMapping
    public String processRegistrationForm(RegistrationForm form, @Autowired RegistrationFormProcessor registrationFormProcessor) {
        registrationFormProcessor.prepareUser(form); // throws NPE - not working
        return "redirect:/login";
    }
}

后:

@Controller
@RequestMapping("/register")
public class RegistrationController {
    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;
    private final RegistrationFormProcessor registrationFormProcessor;

    public RegistrationController(UserRepository userRepository, PasswordEncoder passwordEncoder, RegistrationFormProcessor registrationFormProcessor) {
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
        this.registrationFormProcessor = registrationFormProcessor;
    }

    @PostMapping
    public String processRegistrationForm(RegistrationForm form) {
        registrationFormProcessor.prepareUser(form); //working fine
        return "redirect:/login";
    }
}

但无法解释为什么...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM