• 删除mongodb iteratior报错:java.lang.UnsupportedOperationException: Cursors do not support removal


    错误信息

    Caused by: java.lang.UnsupportedOperationException: Cursors do not support removal
    	at com.mongodb.client.internal.MongoBatchCursorAdapter.remove(MongoBatchCursorAdapter.java:44) ~[mongodb-driver-sync-4.0.3.jar:na]
    	at com.example.demo.service.MongoService.getHisUserInfo(MongoService.java:55) ~[classes/:na]
    	at com.example.demo.MongoDbCommandLinner.run(MongoDbCommandLinner.java:21) ~[classes/:na]
    	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:795) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
    	... 5 common frames omitted

    代码demo

    package com.example.demo.service;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import org.bson.Document;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.mongodb.core.MongoTemplate;
    import org.springframework.stereotype.Service;
    
    import com.mongodb.BasicDBObject;
    import com.mongodb.client.FindIterable;
    import com.mongodb.client.MongoCollection;
    import com.mongodb.client.MongoCursor;
    import com.mongodb.client.MongoDatabase;
    
    @Service
    public class MongoService {
    
        @Autowired
        private MongoTemplate mongoTemplate;
    
        private MongoCollection<Document> getCollection() {
            MongoDatabase mongoDatabase = mongoTemplate.getMongoDbFactory().getMongoDatabase("mytest");
            MongoCollection<Document> collection = mongoDatabase.getCollection("his_data");
            return collection;
        }
    
        public Map<String, Object> getHisUserInfo(String name) {
            Map<String, Object> result = new HashMap<>();
            MongoCollection<Document> collection = getCollection();
    
            BasicDBObject filter = new BasicDBObject();
            filter.append("name", name);
    
            BasicDBObject showCols = new BasicDBObject();
            showCols.append("addr", 1).append("age", 1).append("_id", 0);
    
            FindIterable<Document> find = collection.find(filter).limit(1);
            MongoCursor<Document> iterator = find.iterator();
    
            Document doc = null;
            while (iterator.hasNext()) {
                doc = iterator.next();
                break;
            }
    
            if (doc != null) {
                result.put("name", name);
                result.put("addr", doc.get("addr"));
                result.put("age", doc.get("age"));
            }
    
            iterator.remove();
    
            return result;
        }
    }

    调用getHisUserInfo方法时,出现异常

    测试List遍历删除

    我们知道如果一个集合中的数据遍历获取后,就不再需要了,对于这种情况,边遍历边删除是一种比较好的处理方式,可以节省内存

    public static void main(String[] args) {
            List<String> list = new ArrayList<String>();
            list.add("test 001");
            list.add("test 002");
            list.add("test 003");
            
            System.out.println("before remove: " + list);
            Iterator<String> iterator = list.iterator();
            while(iterator.hasNext()) {
                iterator.remove();
            }
            System.out.println("after remove: " + list);
            
        }

    运行结果

    before remove: [test 001, test 002, test 003]
    Exception in thread "main" java.lang.IllegalStateException
    	at java.util.ArrayList$Itr.remove(Unknown Source)
    	at com.example.demo.CommonTest.main(CommonTest.java:18)

    删除时出现了异常,之前每太注意过这种情况,查看remove方法api介绍

    从这个异常情况的描述信息可知,在调用iterator的remove方法时,要先调用其next方法,否则就会发生这样的异常,再while循环中remove方法调用前调用下next,确实是可以正常删除,此处不再贴出来代码,其实我们如果要清空一个集合,肯定也不会用这种方式来清空,直接调用list的clear方法更好,如果要删除指定的元素,也会调用下next方法,判断其值后进行删除,所以一般也不会出现什么问题。

    Mongodb迭代删除异常原因

    从上述遍历删除从mongodb获取的数据可以看出,已经调用了next方法,但是还会出现异常,究其原因,是由于ArrayList重写了Iterator的remmove方法,从mongodb删除报错的异常信息看,

    MongoBatchCursorAdapter中的remove方法抛出的异常,我们进入到该类,查看其remove方法,

    mongodb不允许我们在取出元素的同时,对其做删除操作

  • 相关阅读:
    bash帮助文档简单学习;bash手册翻译
    jmeter的master、slave模型启动方法
    如何查看pip安装包的所有版本;以及ipython的安装
    简单过下bash/sh脚本基本知识吧
    Celery 启动报错 can_read() got an unexpected keyword argument timeout
    paramiko执行命令超时的问题
    远程的jmeter自动执行完,如何回调通知被调用者“结束”状态
    记录一下:关于mysql数据误删除恢复的问题
    数据库Sharding的基本思想和切分策略
    数据库分库分表(sharding)系列(一) 拆分实施策略和示例演示
  • 原文地址:https://www.cnblogs.com/qq931399960/p/12899618.html
Copyright © 2020-2023  润新知