英文:
NullPointerException getting collection from MongoTemplate
问题
以下是翻译好的内容:
这是我的问题。我有一个连接到MongoDB的Spring Boot应用程序。我创建了一个RESTful API,并且在Controllers上使用MongoTemplate
没有返回任何错误。但是现在,我想在运行应用程序时创建一个线程来分析一些数据。问题是,初始化线程后,当代码到达连接到数据库的语句或将集合分配给变量的语句时,它会返回NullPointerException
。
返回错误的代码如下:
public class TreatmentThread implements Runnable {
@Autowired
MongoTemplate mongoTemplate;
MongoCollection<Document> measurements = mongoTemplate.getCollection("measurements");
@Override
public void run() {
try {
Date today = new Date(System.currentTimeMillis());
List<Bson> pipeline = Arrays.asList(
match(and(
gte("date", new java.util.Date(1598464800000L)),
lte("date", new java.util.Date(1598540400000L)))),
sort(orderBy(descending("date"), descending("hour"))),
group(and(eq("device", "$device"), eq("plant", "$plant")),
push("measurements", "$$ROOT")),
project(exclude("measurements._id", "measurements.plant", "measurements.device", "measurements._class")));
AggregateIterable<AnalyzeMeasurements> result = measurements.aggregate(pipeline, AnalyzeMeasurements.class);
// TODO: 分析结果
} catch (Exception e) {
Log.logger.error("发生了一些错误 " + e);
}
}
}
使用这段代码,它返回错误:
> Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException
> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at java.base/java.lang.reflect.Method.invoke(Method.java:564)
> at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
>Caused by: java.lang.NullPointerException
> at com.rainforest.eco.analytics.TreatmentThread.<init>(TreatmentThread.java:35)
> at com.rainforest.eco.Application.main(Application.java:25)
> ... 5 more
如果我尝试直接在代码中获取集合,它只会返回NullPointerException
,不提供任何其他详细信息。
该线程在Application.java
类中启动:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
Log.logger.info("启动线程:TreatmentThread");
Log.logger.info("启动线程:分析盆栽测量以安排处理");
// 创建包含10个线程的线程池
int numThreads = 10;
final ScheduledExecutorService schExService = Executors.newScheduledThreadPool(numThreads);
// 创建可运行的线程
final Runnable treatmentAnalyzer = new TreatmentThread();
// 线程调度
int minute = 60;
schExService.scheduleWithFixedDelay(treatmentAnalyzer, minute, 5 * minute, TimeUnit.SECONDS);
Log.logger.info("线程已启动:当前正在运行");
}
}
有人知道错误是从哪里产生的吗?
英文:
Here is my problem. I have a Spring Boot application connected to a MongoDB. I created a RESTful API, and using MongoTemplate
on the Controllers did not return any error. But now, I want to create a thread to analyze some data while running the app. The problem es that after that thread is initialized, it returns a NullPointerException
when the code reaches the statement to connect to the database or to assign the collection to a variable.
The code that returns the error is the following:
public class TreatmentThread implements Runnable {
@Autowired
MongoTemplate mongoTemplate;
MongoCollection<Document> measurements = mongoTemplate.getCollection("measurements");
@Override
public void run() {
try {
Date today = new Date(System.currentTimeMillis());
List<Bson> pipeline = Arrays.asList(
match(and(
gte("date", new java.util.Date(1598464800000L)),
lte("date", new java.util.Date(1598540400000L)))),
sort(orderBy(descending("date"), descending("hour"))),
group(and(eq("device", "$device"), eq("plant", "$plant")),
push("measurements", "$$ROOT")),
project(exclude("measurements._id", "measurements.plant", "measurements.device", "measurements._class")));
AggregateIterable<AnalyzeMeasurements> result = measurements.aggregate(pipeline, AnalyzeMeasurements.class);
// TODO: Analyze results
} catch (Exception e) {
Log.logger.error("Some error ocurred " + e);
}
}
}
With that code, it returns the error:
> Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException
> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at java.base/java.lang.reflect.Method.invoke(Method.java:564)
> at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
>Caused by: java.lang.NullPointerException
> at com.rainforest.eco.analytics.TreatmentThread.<init>(TreatmentThread.java:35)
> at com.rainforest.eco.Application.main(Application.java:25)
> ... 5 more
In case I directly try to get the collection in the code, it simply returns a NullPointerException
, not giving any more details.
The thread is launched in the Application.java
class:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
Log.logger.info("Starting Thread: TreatmentThread");
Log.logger.info("Starting Thread: Analyze pot measurements to schedule treatments");
// Create pool with 10 threads
int numThreads = 10;
final ScheduledExecutorService schExService = Executors.newScheduledThreadPool(numThreads);
// Create runnable thread
final Runnable treatmentAnalyzer = new TreatmentThread();
// Thread scheduling
int minute = 60;
schExService.scheduleWithFixedDelay(treatmentAnalyzer, minute, 5 * minute, TimeUnit.SECONDS);
Log.logger.info("Thread Started: Currently Running");
}
}
Does anyone know where the error comes from?
答案1
得分: 2
用new
操作符实例化TreatmentThread
不会自动装配依赖项。因此,MongoTemplate mongoTemplate
为null
,并且随后对它的调用会引发NPE(空指针异常)。
你需要在Application
类中自动装配这样的对象,并将其定义为一个bean(可以在类级别上使用@Component
,或者在方法级别上使用@Bean
):
@Component
public class TreatmentThread implements Runnable {
...
}
@SpringBootApplication
public class Application {
@Autowired
TreatmentThread treatmentThread;
...
}
英文:
Instantiating TreatmentThread
using a new
operator doesn't autowire the dependencies. Therefore MongoTemplate mongoTemplate
is null
and the subsequent call on it throws the NPE.
You need to autowire such object in the Application
class as well as define it as a bean (either @Component
on the class level or @Bean
on the method level):
@Component
public class TreatmentThread implements Runnable {
...
}
@SpringBootApplication
public class Application {
@Autowired
TreatmentThread treatmentThread;
...
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论