每当循环中的迭代次数增加时,我都会收到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++;
        }
    }

上面的逻辑用于基于多个参数从“车辆”表中搜索车辆,其中参数之一是邮政编码。邮政编码的值出现在一个列表中,需要对其进行迭代并将其添加到查询中。

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)在DB中插入zipcode,而不是以USA-xxxxx格式进行查询。更简单,并提高搜索性能。

09-05 02:13