如何在形成HQL查询时解决由于递归引起的java.lang.StackOverflowError
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了如何在形成HQL查询时解决由于递归引起的java.lang.StackOverflowError,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含10494字,纯文字阅读大概需要15分钟。
内容图文
![如何在形成HQL查询时解决由于递归引起的java.lang.StackOverflowError](/upload/InfoBanner/zyjiaocheng/824/7dcee3bb37a4466eb8054ee94c931e2a.jpg)
每当循环中的迭代变得更高时,我就会得到StackOverflowError.我写这样的逻辑:
public List<Vehicle> seacrhCar(Integer from, SearchDto searchDto,List<String> coveredZipcodes) {
String q = "from Vehicle where 1=1";
int i=1;
if(StringUtils.isNotBlank(searchDto.getFromYear()))
q+=" and year>='"+StringUtils.replace(searchDto.getFromYear().trim(), "'", "''")+"'";
if(StringUtils.isNotBlank(searchDto.getToYear()))
q+=" and year<='"+StringUtils.replace(searchDto.getToYear().trim(), "'", "''")+"'";
if(StringUtils.isNotBlank(searchDto.getManufacturer()))
q+=" and make='"+StringUtils.replace(searchDto.getManufacturer().trim(), "'", "''")+"'";
if(StringUtils.isNotBlank(searchDto.getCarModel()))
q+=" and model='"+StringUtils.replace(searchDto.getCarModel(), "'", "''")+"'";
if(StringUtils.isNotBlank(searchDto.getTrim()))
q+=" and trim='"+StringUtils.replace(searchDto.getTrim().trim(), "'", "''")+"'";
if(StringUtils.isNotBlank(searchDto.getMinPrice()))
q+=" and priceBaseMsrp>="+searchDto.getMinPrice().trim();
if(StringUtils.isNotBlank(searchDto.getMaxPrice()))
q+=" and priceBaseMsrp<="+searchDto.getMaxPrice().trim();
if(coveredZipcodes.size()>0) {
q+=" and (";
for(String zip : coveredZipcodes) {
q+="zipcode LIKE '%"+zip+"'";
q+=(i==coveredZipcodes.size())?")":" or ";
i++;
}
}
q+=" group by vehicle";
List<Vehicle> vehicles = sessionFactory.getCurrentSession().createQuery(q).setFirstResult(from).setMaxResults(10).setFlushMode(FlushMode.ALWAYS).list();
return vehicles;
这是上面代码中导致问题的部分:
if(coveredZipcodes.size()>0) {
q+=" and (";
for(String zip : coveredZipcodes) {
q+="zipcode LIKE '%"+zip+"'";
q+=(i==coveredZipcodes.size())?")":" or ";
i++;
}
}
上述逻辑用于基于多个参数从Vehicle表中搜索车辆,其中一个参数是zipcodes. zipcodes的值列在一个列表中,需要迭代并添加到查询中.
zipcodeList(coveredZipcodes)的大小取决于用户从他当前的邮政编码中选择的半径(距离),例如,当用户从他当前的邮政编码中选择10英里半径时,邮政编码的数量将为200,并且随着里程数的增加,邮政编码的数量也会增加.高达80-90英里,我没有得到任何错误,但当我选择100英里或更多时,它会抛出StackOverflowError.
这是堆栈跟踪:
org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.StackOverflowError
org.springframework.web.servlet.DispatcherServlet.triggerAfterCompletionWithError(DispatcherServlet.java:1284)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:965)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
根本原因
java.lang.StackOverflowError的
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2654)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanExpr(SqlGeneratorBase.java:840)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2685)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanExpr(SqlGeneratorBase.java:840)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2685)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanExpr(SqlGeneratorBase.java:840)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2685)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanExpr(SqlGeneratorBase.java:840)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2685)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanExpr(SqlGeneratorBase.java:840)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2685)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanExpr(SqlGeneratorBase.java:840)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2685)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanExpr(SqlGeneratorBase.java:840)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2685)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanExpr(SqlGeneratorBase.java:840)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2685)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanExpr(SqlGeneratorBase.java:840)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2685)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanExpr(SqlGeneratorBase.java:840)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2685)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanExpr(SqlGeneratorBase.java:840)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2685)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanExpr(SqlGeneratorBase.java:840)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2685)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanExpr(SqlGeneratorBase.java:840)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2685)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanExpr(SqlGeneratorBase.java:840)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2685)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanExpr(SqlGeneratorBase.java:840)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2685)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanExpr(SqlGeneratorBase.java:840)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2685)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanExpr(SqlGeneratorBase.java:840)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2685)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanExpr(SqlGeneratorBase.java:840)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2685)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanExpr(SqlGeneratorBase.java:840)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2685)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanExpr(SqlGeneratorBase.java:840)
org.hibernate.hql.internal.antlr.SqlGeneratorBase.booleanOp(SqlGeneratorBase.java:2685)
经过一些研究后我才明白这个问题,但我该如何解决这个问题呢?
解决方法:
感谢大家提出的好建议,特别是@Pratik.最后,这是一段对我有用的代码.
if(coveredZipcodes.size()>0) {
q.append(" and substring(zipcode,5,9) in (:zipcodes)");
}
q.append(" group by vehicle");
Query query = sessionFactory.getCurrentSession().createQuery(q.toString());
if(coveredZipcodes.size()>0)
query.setParameterList("zipcodes", coveredZipcodes);
List<Vehicle> vehicles = query.setFirstResult(from).setMaxResults(10).list();
return vehicles;
然而,我将用’zipcode’替换’substring(zipcode,5,9)’部分,并将在数据库中以xxxxx格式(例如,12345)插入zipcode,而不是将其保留为USA-xxxxx格式以进行查询更简单,增加搜索性能.
内容总结
以上是互联网集市为您收集整理的如何在形成HQL查询时解决由于递归引起的java.lang.StackOverflowError全部内容,希望文章能够帮你解决如何在形成HQL查询时解决由于递归引起的java.lang.StackOverflowError所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。