使用Morphia查询含Java HashMap属性的对象列表时出现空指针异常
嘿,我之前在使用Morphia和MongoDB开发Java项目时,也碰到过类似的单个查询正常但列表查询抛NullPointerException的情况,咱们一步步来排查解决:
检查实体类的映射完整性
先确认你的实体类上有没有正确标注@Entity注解,并且指定的集合名称和MongoDB中的实际集合名一致。另外,@Id字段的类型要和数据库中_id的类型匹配(比如用ObjectId或者字符串,别和数据库里的类型不对应)。如果有自定义字段,确保没有遗漏@Property注解,也别误把需要持久化的字段用transient修饰——Morphia默认会忽略transient字段,要是数据库里存在这个字段,映射时可能会引发异常。核对列表查询的代码逻辑
单个查询用datastore.find(YourEntity.class).field("xxx").equal(value).get()没问题,但查列表时要确认用的是find().asList(),而不是错误地调用了get()(get()只返回单个对象,列表查询用它会返回null)。另外,拿到列表后别直接操作(比如遍历、取第一个元素),一定要先判断列表是否为空:List<YourEntity> entities = datastore.find(YourEntity.class).asList(); // 先做非空判断再操作 if (entities != null && !entities.isEmpty()) { // 处理数据 }还要确认
datastore实例本身不是null,有些依赖注入或者初始化的问题会导致查询时拿到的Datastore是空的。验证版本兼容性
Morphia不同版本对MongoDB的支持差异很大,比如Morphia 2.x和3.x的API变化非常多。如果你的Morphia版本太旧,而MongoDB是较新的版本,可能会出现列表查询时的映射异常。可以尝试升级Morphia到与MongoDB兼容的版本,或者核对官方文档的版本匹配说明。检查数据库数据的一致性
单个查询的那条数据可能刚好符合实体类的映射规则,但集合里其他数据可能存在问题——比如某个字段的类型和实体类不匹配(实体类是Integer,数据库里存了字符串),或者存在缺失必填字段的文档。这种情况下,查询列表时Morphia映射失败会间接导致NPE。可以用MongoDB Compass或者shell手动查询集合里的所有数据,排查有没有不符合实体类定义的文档。启用Morphia调试日志
打开Morphia的调试日志,能看到查询时生成的MongoDB语句,以及映射过程中的细节,更容易定位问题。比如在logback配置里添加:<logger name="dev.morphia" level="DEBUG"/>查看日志里的查询语句是否正确,有没有映射报错的信息。
内容的提问来源于stack exchange,提问作者Waqar Ul Khaf

