При извлечении существующей коллекции Mongo DB выдается исключение нулевого указателя

У меня есть созданная 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;
    }
}

Пользователь.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» имеет значение null в 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 (собственный метод) ~[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]

Но та же самая функция в остальном API работает нормально.

Вот как я использую UserSeedder в Alert.java

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;
    }
}

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
948
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы должны аннотировать класс UserSeeder с помощью @Service или @Component, чтобы Spring мог создавать и обрабатывать экземпляр этого класса как управляемый bean-компонент Spring, и таким образом внедрение зависимостей должно работать правильно, предполагая, что Spring сканирует пакет com.weatherdata.api.users.

Другой альтернативой может быть определение @Bean в классе @Configuration.

Вы можете найти больше информации о внедрении зависимостей в Spring во многих статьях и соответствующей документации в Интернете (например, ссылка 1 или ссылка 2 и т. д.).

Обновлять

Внедрение зависимостей не работает, когда вы вручную создаете экземпляры объектов, вы используете

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);
  }
}

пакет сканируется весной (@ComponentScan(basePackages = "com.weatherdata.api.users")? вы используете загрузку Spring?

lzagkaretos 24.12.2020 21:46

не могли бы вы добавить, как вы вызываете класс UserSeeder? вы используете новое ключевое слово?

lzagkaretos 24.12.2020 21:51

Отредактировано и добавлено к вопросу

Dineth S Gimhana 24.12.2020 21:52

Обновлен мой ответ, внедрение зависимостей не работает при использовании ключевого слова new для создания экземпляров ваших объектов.

lzagkaretos 24.12.2020 21:56

Давайте продолжим обсуждение в чате.

Dineth S Gimhana 24.12.2020 21:58

Как заставить подкласс Spring управлять Alert?

Dineth S Gimhana 24.12.2020 22:01
Ответ принят как подходящий

Вы должны использовать аннотацию SterioType @Service поверх классов, которые имеют бизнес-логику, и @Component поверх классов, которые являются общими для всех уровней приложений или служебных классов, когда вы аннотируете @Springbootapplication поверх основного класса, в котором он имеет базовый @ComponentScan(basePackages=" имя пакета, в котором находится основной класс"), он автоматически создает экземпляры классов, которые находятся в базовом пакете.

Другие вопросы по теме