【问题标题】:When retrieving existing Mongo DB Collection gives null pointer exception检索现有的 Mongo DB 集合时出现空指针异常
【发布时间】:2021-04-03 04:16:52
【问题描述】:

我创建了一个带有数据的 MongoDB,但是在检索特定集合中的所有文档时,我的程序给出了一个空指针异常。

这是我的代码, UserRepository.java

package com.weatherdata.api.dbconnector;

import com.weatherdata.api.users.User;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface UserRepository extends MongoRepository<User,String> {
    
}


UserSeeder.java

package com.weatherdata.api.users;

import com.weatherdata.api.dbconnector.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

public class UserSeeder {
    @Autowired
    UserRepository userRepository;

    public List<User> getAllUsers(){
        List <User> allUsers = this.userRepository.findAll();
        return allUsers;
    }
}

User.java

package com.weatherdata.api.users;


import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document;

import java.util.HashSet;
import java.util.Set;
@Document(collection = "users")
public class User {
    @Id
    private String id;
    private String username;
    private String email;
    private String mobile;
    private String method;
    private String password;

    @DBRef
    private Set<Role> roles = new HashSet<>();

    public User() {
    }

    public User(String username, String email,String mobile,String method, String password) {
        this.username = username;
        this.email = email;
        this.mobile = mobile;
        this.method = method;
        this.password = password;
    }

    public String getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    public String getMethod() {
        return method;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Set<Role> getRoles() {
        return roles;
    }

    public void setRoles(Set<Role> roles) {
        this.roles = roles;
    }
}


错误是,

java.lang.NullPointerException:无法调用“com.weatherdata.api.dbconnector.UserRepository.findAll()”,因为“this.userRepository”为空 在 com.weatherdata.api.users.UserSeeder.getAllUsers(UserSeeder.java:13) ~[classes/:na] 在 com.weatherdata.api.filter.Alert.isExceeded(Alert.java:20) ~[classes/:na] 在 com.weatherdata.api.controller.SensorController.insert(SensorController.java:56) ~[classes/:na] 在 java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] 在 java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[na:na] 在 java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] 在 java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na] 在 org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197) ~[spring-web-5.3.2.jar:5.3.2] 在 org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141) ~[spring-web-5.3.2.jar:5.3.2] 在 org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.3.2.jar:5.3.2] 在 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) ~[spring-webmvc-5.3.2.jar:5.3.2] 在 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.2.jar:5.3.2] 在 org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.2.jar:5.3.2] 在 org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1061) ~[spring-webmvc-5.3.2.jar:5.3.2] 在 org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:961) ~[spring-webmvc-5.3.2.jar:5.3.2] 在 org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.2.jar:5.3.2] 在 org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.2.jar:5.3.2]

但在rest api中的相同功能工作正常。

这就是我在 Alert.java 中使用 UserSedder 的方式

package com.weatherdata.api.filter;

import com.weatherdata.api.users.User;
import com.weatherdata.api.users.UserSeeder;

import java.util.List;

public abstract class Alert implements AlertType {
    private double thresholdValue;
    private List<User> userList;

    @Override
    public double getThreshold() {
        return this.thresholdValue;
    }

    @Override
    public boolean isExceeded(double dataValue) {
        if(thresholdValue < dataValue){
            userList = new UserSeeder().getAllUsers();
            System.out.println(userList.stream().count());
            return true;
        }
        else{
            return false;
        }
    }

    public double getThresholdValue() {
        return thresholdValue;
    }

    public void setThresholdValue(double thresholdValue) {
        this.thresholdValue = thresholdValue;
    }
}

【问题讨论】:

    标签: java spring spring-boot


    【解决方案1】:

    你应该用@Service@Component注释类UserSeeder,让Spring创建并处理这个类的一个实例作为spring托管bean,这样,依赖注入应该正常工作,假设Spring扫描包@987654327 @。

    另一种选择是在@Configuration 类中定义@Bean

    您可以在许多在线文章和相关文档(例如link 1link 2 等)中找到有关 Spring 依赖注入的更多信息。

    更新

    当您手动实例化对象时,依赖注入不起作用,您正在使用

    new UserSeeder()

    解决您的问题的一种方法是使 Alert 子类也管理 spring,并将 @Autowired 用于类型为 UserSeeder 的实例属性,从而删除 new 的使用。

    你可以使用类似的东西(根据你的需要改变)

    public abstract class Alert implements AlertType {
    
      private UserSeeder userSeeder;
    
      public Alert (UserSeeder userSeeder) {
        this.userSeeder = userSeeder;
      }
    
      // change new UserSeeder() with this.userSeeder
    }
    
    @Service
    public class AlertService extends Alert {
    
      @Autowired
      public AlertService(UserSeeder userSeeder) {
        super(userSeeder);
      }
    }
    

    【讨论】:

    • 是spring扫描的包吗(@ComponentScan(basePackages = "com.weatherdata.api.users")?你用的是Spring boot吗?
    • 您能否添加您如何调用 UserSeeder 类?你使用新关键字吗?
    • 已编辑并添加到问题中
    • 更新了我的答案,使用 new 关键字实例化对象时,依赖注入不起作用。
    【解决方案2】:

    您必须在具有业务逻辑的类上使用 SterioType 注释 @Service 并在对所有应用程序层或实用程序类通用的类上使用 @Component 当您在其具有底层 @ComponentScan( basePackages="主类所在的包名")它会自动创建在basepackage下的类的实例。

    【讨论】:

      猜你喜欢
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多