在使用JPA的仓储repository进行查询时,经常用到findAllbyId的方法: repository.findAllbyId()

但如果像下面的代码,当list的size量太大的话,就会报栈溢出的的错误:java.lang.StackOverflowError

@RequestMapping("/stackOverFlow")
public Integer stackOverFlow() { List<String> ids = new ArrayList<>();
for (int i = 0; i < 5000; i++) {
ids.add("123123123123");
}
List<BillDO> allById = dwBillRepository.findAllById(ids); return allById.size();
}

报错信息如下:

Caused by: java.lang.StackOverflowError
at antlr.BaseAST.toString(BaseAST.java:333) ~[antlr-2.7.7.jar:?]
at antlr.BaseAST.toStringList(BaseAST.java:341) ~[antlr-2.7.7.jar:?]
at antlr.BaseAST.toStringList(BaseAST.java:347) ~[antlr-2.7.7.jar:?]
at antlr.BaseAST.toStringList(BaseAST.java:347) ~[antlr-2.7.7.jar:?]
at antlr.BaseAST.toStringList(BaseAST.java:347) ~[antlr-2.7.7.jar:?]
at antlr.BaseAST.toStringList(BaseAST.java:347) ~[antlr-2.7.7.jar:?]
at antlr.BaseAST.toStringList(BaseAST.java:347) ~[antlr-2.7.7.jar:?]
at antlr.BaseAST.toStringList(BaseAST.java:347) ~[antlr-2.7.7.jar:?]
at antlr.BaseAST.toStringList(BaseAST.java:347) ~[antlr-2.7.7.jar:?]
at antlr.BaseAST.toStringList(BaseAST.java:347) ~[antlr-2.7.7.jar:?]
at antlr.BaseAST.toStringList(BaseAST.java:347) ~[antlr-2.7.7.jar:?]

原因就是在拼sql时方法入栈太深,超过了jvm允许的最大深度,也就是递归调用的太深了。

public String toStringList() {
String var2 = "";
if (this.getFirstChild() != null) {
var2 = var2 + " (";
} var2 = var2 + " " + this.toString();
if (this.getFirstChild() != null) {
var2 = var2 + ((BaseAST)this.getFirstChild()).toStringList();
} if (this.getFirstChild() != null) {
var2 = var2 + " )";
} if (this.getNextSibling() != null) {
var2 = var2 + ((BaseAST)this.getNextSibling()).toStringList();
} return var2;
}

解决方法就是不要递归的太深。或者调整JVM参数栈大小默认为1m,可以调整到10m,看看不能解决问题,但这样做不推荐。会影响线程数,从而影响系统性能。

具体到上面的问题就是一次不要查太多的数据。如果in的数量有5000,我们就分开查询一次只查1000,查5次。再把结果组合在一起。

如果每个业务都单独写的话,就太麻烦了,可以写个公共的方法,如下: JPA_QUERY_LIST_MAX_SIZE是一个常量数据值,如1000个查一次。这里使用了并行查询,查询效率更高。

public <T> List<T> findAll(List<String> ids, Function<List<String>, List<T>> func) {

        List<List<String>> idGroups = Lists.partition(ids, JPA_QUERY_LIST_MAX_SIZE);
        ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(idGroups.size());
executor.setKeepAliveTime(10, TimeUnit.SECONDS);//解决线程不退出的问题
executor.allowCoreThreadTimeOut(true);

return idGroups
.stream()
.collect(ParallelCollectors
.parallelToList(i -> func.apply(i), executor, idGroups.size()))
.join()
.stream()
.flatMap(Collection::stream)
.collect(toList());
}

以上代码利用如一个第三方的库:需要引用:

<dependency>
<groupId>com.pivovarit</groupId>
<artifactId>parallel-collectors</artifactId>
<version>1.1.0</version>
</dependency>

这里引出一个题外话,如果in查询数据量很大的话,可能会导致索引失效的问题。需要重点看一下。

java.lang.StackOverflowError解决的更多相关文章

  1. java.lang.StackOverflowError 解决方法

    ♦ java.lang.StackOverflowError : 由于深度递归,抛出此错误以指示应用程序的堆栈已耗尽. 在递归中,一个方法在执行期间调用自己.递归被认为是一种强大的通用编程技术,但必须 ...

  2. java.lang.StackOverflowError 解决办法

    java.lang.StackOverflowError com.sxt.servlet.servlet1.LoginServlet.doGet(LoginServlet.java:15) com.s ...

  3. Spark出现java.lang.stackoverflowerror的解决方法

    正在测试的程序需要多次迭代(400+次),每次迭代有复杂的运算 迭代到100多次的时候报java.lang.stackoverflowerror的错误 解决方法:先checkpoint()再count ...

  4. struts2 java.lang.StackOverflowError org.apache.struts2.json.JSONWriter

    1. 问题描述: 页面通过异步访问action,    action的方法通过map封装数据,struts的result的type设置为json,后台报错 六月 25, 2016 6:54:33 下午 ...

  5. android布局太深导致的 java.lang.StackOverflowError

    E/AndroidRuntime( 1900): java.lang.StackOverflowError E/AndroidRuntime( 1900):     at android.graphi ...

  6. 【转】java.lang.StackOverflowError

    http://blog.csdn.net/g19920917/article/details/8765638 出现一个java.lang.StackOverflowError异常.弄了半天,又是问高手 ...

  7. servlet运行“/*”引起的java.lang.StackOverflowError

    <servlet> <servlet-name>login</servlet-name> <servlet-class>com.jd.login.UI. ...

  8. Java EE之Hibernate异常总结【5】java.lang.StackOverflowError[栈溢出]

    Exception in thread "main" java.lang.StackOverflowError at java.lang.reflect.InvocationTar ...

  9. android java.lang.StackOverflowError

    转自:http://hi.baidu.com/424660053/item/bee53a2633870dccddf69a17 最近做项目出现一个java.lang.StackOverflowError ...

随机推荐

  1. HDU4587--TWO NODES(无向图割点,暴力出奇迹)这是我见过的时间最长的题。。。

    TWO NODES Time Limit: 24000/12000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total ...

  2. R_Studio(学生成绩)对数值型数据进行统计量分析

    对“Gary.csv”中的成绩数据进行统计量分析 基础数据分析 均值 中位数 极差   标准差   变异系数 1/4分位数 3/4分位数 四分位间距... ...分析 setwd('D:\\data' ...

  3. Unity3D_(游戏)甜品消消乐02_游戏核心算法

    甜品消消乐01_游戏基础界面 传送门 甜品消消乐02_游戏核心算法 传送门 甜品消消乐03_游戏UI设计    传送门 GameManager脚本上修改Fill Time可以改变消消乐移动速度 实现过 ...

  4. Unity3D_(游戏)卡牌04_游戏界面

        启动屏界面.主菜单界面.选关界面.游戏界面 卡牌01_启动屏界面 传送门 卡牌02_主菜单界面 传送门 卡牌03_选关界面 传送门 卡牌04_游戏界面    传送门 选关界面效果 (源代码在文 ...

  5. php的intval函数

    PHP intval() 函数 PHP 可用的函数PHP 可用的函数 intval() 函数用于获取变量的整数值. intval() 函数通过使用指定的进制 . PHP , PHP , PHP 语法 ...

  6. MyBaits理解?

    (1)MyBaits是一个基于Java的持久层框架,支持普通或定制化SQL查询.存储过程以及高级映射,使用XML或注解来配置和映射信息. (2)应用程序使用SQLSessionFactory实例,一个 ...

  7. Spring理解?

    (1)Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架,是解决企业应用开发的复杂性,为J2EE应用提供了全方位的整合框架,在Spring框架下实现多个子框架的组合. (2)Sp ...

  8. JSTL标签语言

    ******概述: JSTL是apache对EL表达式的扩展(也就是说JSTL依赖EL),JSTL是标签语言! JSTL标签使用以来非常方便,它与JSP动作标签一定,只不过它不是JSP内置的标签,需要 ...

  9. java正则表达式详细总结

    Java 提供了功能强大的正则表达式API,在java.util.regex 包下.本教程介绍如何使用正则表达式API. 正则表达式 一个正则表达式是一个用于文本搜索的文本模式.换句话说,在文本中搜索 ...

  10. leetcode-hard-array-54. Spiral Matrix-NO

    mycode 思路:这种方格图一定要预先设置定位的变量,例如最大的长.宽,变化中的长.宽,在while循环中也要不断判断是否满足break条件 class Solution(object): def ...