You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

遍历ArrayList时遭遇java.util.ConcurrentModificationException异常

解决Hibernate持久化集合遍历中的ConcurrentModificationException

你遇到的问题根源其实很明确:你遍历的myObjectList并不是普通的ArrayList,而是Hibernate管理的PersistentCollection(持久化集合)。当你在循环里调用objectRepository.save(obj)时,Hibernate会悄悄同步更新这个集合的内部状态(比如刷新缓存、同步实体状态),这就导致迭代器在检查集合修改次数(modCount)时发现前后不一致,直接抛出ConcurrentModificationException——哪怕你只是修改对象属性,没有显式增删集合元素,Hibernate的内部操作也可能触发这个异常。

下面给你几个可行的解决方案,按推荐程度排序:

1. 使用JPQL批量更新(最优方案)

如果你的需求只是批量修改这些对象的endDate和active状态,完全不需要把所有对象加载到内存里。直接用JPQL执行批量更新,在数据库层面完成操作,既高效又彻底避免迭代问题:

String batchUpdateJpql = "UPDATE YourEntity o SET o.endDate = :targetDate, o.active = false";
entityManager.createQuery(batchUpdateJpql)
    .setParameter("targetDate", someDate)
    .executeUpdate();

注意:把YourEntity换成你实际的实体类名,如果需要过滤特定数据,可以在JPQL里加WHERE子句补充条件。

2. 转成普通集合再遍历

如果必须加载对象到内存处理(比如还有其他业务逻辑要执行),可以先把Hibernate的持久化集合转成普通的ArrayList,脱离Hibernate的管理后再遍历:

// 把持久化集合转成普通ArrayList,脱离Hibernate的状态跟踪
List<YourEntity> tempList = new ArrayList<>(myObjectList);

for(YourEntity obj : tempList) {
    obj.setEndDate(someDate);
    obj.setActive(false); // 这里你原来写的isActive(false)应该是setActive的笔误吧?
    objectRepository.save(obj);
}

这样遍历的是独立的临时列表,Hibernate对原集合的内部修改不会影响这个列表的迭代过程,自然不会抛出异常。

3. 使用Hibernate ScrollableResults遍历(适合大数据量)

如果数据量很大,转成临时列表会占用过多内存,可以用Hibernate的ScrollableResults来逐行加载实体,同时定期flush/clear会话避免内存溢出:

Session session = entityManager.unwrap(Session.class);
ScrollableResults results = session.createQuery("FROM YourEntity")
    .scroll(ScrollMode.FORWARD_ONLY);

int counter = 0;
while (results.next()) {
    YourEntity obj = (YourEntity) results.get(0);
    obj.setEndDate(someDate);
    obj.setActive(false);
    session.save(obj);

    // 每处理50条就flush并clear,释放内存
    if (++counter % 50 == 0) {
        session.flush();
        session.clear();
    }
}

另外提个小细节:你代码里的obj.isActive(false)应该是setActive(false)的笔误,is开头的方法一般是属性的getter,设置属性要用setter哦。

内容的提问来源于stack exchange,提问作者Naren

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 21:32:28