NullPointerException在从MongoTemplate获取集合时发生

huangapple go评论89阅读模式
英文:

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&lt;Document&gt; measurements = mongoTemplate.getCollection(&quot;measurements&quot;);
	
	@Override
	public void run() {
		try {
			Date today = new Date(System.currentTimeMillis());
			
			List&lt;Bson&gt; pipeline = Arrays.asList(
					match(and(
						gte(&quot;date&quot;, new java.util.Date(1598464800000L)), 
						lte(&quot;date&quot;, new java.util.Date(1598540400000L)))), 
					sort(orderBy(descending(&quot;date&quot;), descending(&quot;hour&quot;))), 
					group(and(eq(&quot;device&quot;, &quot;$device&quot;), eq(&quot;plant&quot;, &quot;$plant&quot;)), 
						push(&quot;measurements&quot;, &quot;$$ROOT&quot;)), 
					project(exclude(&quot;measurements._id&quot;, &quot;measurements.plant&quot;, &quot;measurements.device&quot;, &quot;measurements._class&quot;)));
			
			AggregateIterable&lt;AnalyzeMeasurements&gt; result = measurements.aggregate(pipeline, AnalyzeMeasurements.class);
			
			// TODO: Analyze results
		} catch (Exception e) {
			Log.logger.error(&quot;Some error ocurred &quot; + 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(&quot;Starting Thread: TreatmentThread&quot;);
		Log.logger.info(&quot;Starting Thread: Analyze pot measurements to schedule treatments&quot;);
		//  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(&quot;Thread Started: Currently Running&quot;);
    }
}

Does anyone know where the error comes from?

答案1

得分: 2

new操作符实例化TreatmentThread不会自动装配依赖项。因此,MongoTemplate mongoTemplatenull,并且随后对它的调用会引发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;
...
}

huangapple
  • 本文由 发表于 2020年8月28日 02:31:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/63622212.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定