【问题标题】:MongoDB throws NullPointerException in Class DBTCPConnectorMongoDB 在 DBTCPConnector 类中抛出 NullPointerException
【发布时间】:2014-06-05 09:42:12
【问题描述】:

我正在尝试将 MongoDB 与 Spring Data MongoDB 框架结合使用。我尝试使用官方的Spring Reference Documentation 和一些像Hello-World-Demo 这样的简单示例来连接到我的本地数据库并插入+检索一些集合和文档。

实际上,一开始我将使用 MongoTemplate 来保持简单。但是现在我遇到了以下问题。

当我使用带有注释的 Spring Configuration 配置连接到本地数据库所需的设置时,一切正常。 否则,当我使用 XML 进行配置时,我会在 com.mongodb.DBTCPConnector.getClusterDescription 处遇到 java.lang.NullPointerException

这是我的配置文件和连接数据库的示例代码:

用例 1 - 带有注释的 Spring 配置:

//package, imports etc. here
@Configuration
public class MongoConfiguration {

    public @Bean MongoDbFactory mongoDbFactory() throws Exception {
    return new SimpleMongoDbFactory(new MongoClient(), "Test1");
    }

    public @Bean MongoTemplate mongoTemplate() throws Exception {
    return new MongoTemplate(mongoDbFactory());
    }
}

像这样使用配置类...

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MongoConfiguration.class);
MongoOperations mongoOperation = (MongoOperations) ctx.getBean("mongoTemplate");
ctx.close();
for (String s : mongoOperation.getCollectionNames()) {
    System.out.println(s);
}

.. 创建这个输出:

documents
leute
system.indexes
system.users

用例 2 - XML 配置 (SpringConfig2.xml):

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd
      http://www.springframework.org/schema/data/mongo
      http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <mongo:mongo host="127.0.0.1" port="27017" />
    <mongo:db-factory dbname="Test1" />

    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
    </bean> 
</beans>

像这样使用配置文件...

GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("SpringConfig2.xml");
MongoOperations mongoOperation = (MongoOperations) ctx.getBean("mongoTemplate");
ctx.close();
for (String s : mongoOperation.getCollectionNames()) {
    System.out.println(s);
}

.. 导致此错误

java.lang.NullPointerException
    at com.mongodb.DBTCPConnector.getClusterDescription(DBTCPConnector.java:404)
    at com.mongodb.DBTCPConnector.getMaxBsonObjectSize(DBTCPConnector.java:653)
    at com.mongodb.Mongo.getMaxBsonObjectSize(Mongo.java:641)
    at com.mongodb.DBCollectionImpl.find(DBCollectionImpl.java:81)
    at com.mongodb.DBCollectionImpl.find(DBCollectionImpl.java:66)
    at com.mongodb.DB.getCollectionNames(DB.java:510)
    at org.springframework.data.mongodb.core.MongoTemplate$13.doInDB(MongoTemplate.java:1501)
    at org.springframework.data.mongodb.core.MongoTemplate$13.doInDB(MongoTemplate.java:1499)
    at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:394)
    at org.springframework.data.mongodb.core.MongoTemplate.getCollectionNames(MongoTemplate.java:1499)
    at test.main(Test.java:28)

在调试DBTCPConnector.getClusterDescription时,似乎在第二种情况下,私有类变量cluster由于某种原因没有被实例化,导致描述的错误。

我想知道的是:我在我的 XML 配置中或在使用此配置/上下文时做错了什么?为什么使用xml配置会报错,而使用注解配置就可以了?

基本上(最后)我只是“复制+粘贴”了 Spring / Spring Data MongoDB 官方参考资料中的代码示例。

如果有任何帮助/建议,我将不胜感激 :)

【问题讨论】:

  • PS:我在 Win 7 x64 上使用最新的MongoDB(写这篇文章时是 2.6.1 版)。以及来自GitHub 的最新 Spring Data MongoDB 框架(实际上是“1.5.0.RELEASE”)
  • 用例 2 -> 是否需要立即关闭上下文? ctx.close();
  • 对于这个测试用例,我只需要调用 ctx.getBean("mongoTemplate"); 然后就不再需要它了。我在这里关闭它,因为当我不这样做时,Eclipse 会抱怨“资源泄漏”(尽管我不确定它是否真的有必要)。
  • 我使用相同的配置执行,对我有用。你参考mkyong.com/mongodb/spring-data-mongodb-hello-world-example了吗?
  • @TusharMishra:这就是我所指的示例,除了官方春季文档(第 4 章 -> 4.3.5)

标签: java xml spring mongodb


【解决方案1】:

感谢来自 cmets 中 Tushar Mishra 的提示,我能够追踪错误的根源以及为什么它在一种情况下发生而在另一种情况下没有发生。 我会尝试简短地解释一下,也许它会节省一些研究时间(或者如果我再次遇到这个或类似的错误,请记住我)。

当使用 ctx.close() 关闭 AnnotationConfigApplicationContext 对象 (UC1) 或 AnnotationConfigApplicationContext 对象 (UC2) 时,来自某处 org.springframework.beans.factory.DisposableBean#destroy() 被调用。据我了解,其中使用的单例 bean 通过调用 destroy() 方法被销毁 每个豆子。

简而言之:关闭 XXApplicationContext 对象也会破坏 MongoFactoryBean 并随之关闭与 MongoDB 的连接。 因此,在描述的位置使用 c**tx.close()** 会导致在下一行的关闭连接上使用 MongoOperations-object,从而导致描述的 NullPointerException。

以及为什么带有注释 (UC1) 的示例代码运行良好,而使用 XML (UC2) 配置的示例代码只是因 NullPointerException 而中断: 在 UC1 中,org.springframework.beans.factory.DisposableBean#destroy() 调用被一些 DisposableBeanMethodInterceptor 中断,它尝试重定向到 dispose() 方法。 但是 MongoFactoryBean 中没有实现任何方法,因此 Mongo-connection 保持活动状态并且即使在调用 ctx.close() 之后也可以使用。我认为连接稍后会被垃圾收集器杀死,导致同样的错误。

我还不知道该怎么做。如果我应该自己实现一个 dispose() 方法或类似的东西。但至少我明白了,为什么这个代码示例的行为不同,虽然应该做同样的事情。

也许它可以帮助某人。再次感谢 Tushar,为正确的方向提供提示。

【讨论】:

    猜你喜欢
    • 2017-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多