使用jpa时,调用saveAll()方法报More than one row with the given identifier was found

导读:本篇文章讲解 使用jpa时,调用saveAll()方法报More than one row with the given identifier was found,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

业务场景:

采集服务持续采集数据并放入容器中,每当容器的数量大于1000时,会将容器内的数据放入缓存容器,并清空容器,执行一次保存缓存容器的操作,保存结束后清空缓存数据。

报错场景:

在保存这1000条缓存容器的数据时候偶尔会报More than one row with the given identifier was found…的错误

一般情况这个错误:More than one row with the given identifier was found…..都是查询的时候发生,这次发现在保存时任然也会出现这样的错误。接下来写了一个test代码:

@Component
public class ThreadTest2 {

    CollectDataDao collectDataDao;

    @Autowired
    public void setCollectDataDao(CollectDataDao collectDataDao) {
        this.collectDataDao = collectDataDao;
    }

    public void testSaveAll() throws  InterruptedException {
        List<CollectData> collectDataList = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            CollectData collectData = new CollectData();
            collectData.setApmac("123");
            collectData.setMac("321");
            collectData.setCreatedTime(new Date());
            collectData.setDate(new Date());
            collectData.setStatus(i);
            collectDataList.add(collectData);
        }
        for (int j = 0; j < 10; j++) {
            try {
                CollectData save = collectDataDao.save(collectDataList.get(0));
                CollectData save1 = collectDataDao.save(collectDataList.get(1));
                CollectData save2 = collectDataDao.save(collectDataList.get(2));
                CollectData save3 = collectDataDao.save(collectDataList.get(0));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

当程序save3时就会报这样的错误,通过debugger发现通过save方法(这里主键id是自增)原对象会被填充自生成的id,当再一次被保存时就会产生上面的异常。

我们知道使用jpa时,有id的会被执行更新操作,而这里是报错,同过查看源码可以看到

使用jpa时,调用saveAll()方法报More than one row with the given identifier was found

jpa在保存的时候会判断是否是一个新的对象,如果是一个新的对象,并且存在id才会执行更新操作。

结论:

jpa在保存的时候如果对同一个对象保存多次就会报More than one row with the given identifier was found的异常。

 

回到项目的问题,在批量保存的时候报的这个错误的原因通过分析可以知道,如果容器的数量到达1000时容器里的数据就会放到缓存容器,原容器被清空,在保存缓存容器数据还没保存结束,容器又达到1000,此时容器又会将数据放入缓存容器中并再保存,导致缓存容器存在2000条数据并有一些已经保存,最后造成了异常。

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/5350.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!