Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring JPA deleteInBatch causes StackOverflow

I have a question to deleting Items from db using deleteInBatch. I have an object A having a list of Objects B like:

class A {
private List <B>;
}

The list contains more than 7k elements. So now I have to remove A and all its elements. I tried via deleteInBatch but I get

org.springframework.web.util.NestedServletException: Handler processing failed;
nested exception is java.lang.StackOverflowError

Deleting the items with a sipmle delete method works but it takes more than 5 minutes. My delete code is:

public void delete(Long id) {
A a = repository.findOne(id);
deleteElements(a);
repository.delete(a);
}

private void deleteElements(A a) {
repository.deleteInBatch(a.getListOfB);
}

Is there a good solution to speed up the deleting process or how to change so that deleteinbatch does not take all hibernate stack - without increasing it?

The complete Stacktrace:

org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.StackOverflowError
org.springframework.web.servlet.DispatcherServlet.triggerAfterCompletionWithError(DispatcherServlet.java:1259)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:163)
net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:206)
net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:179)
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)

And so on...

root cause

java.lang.StackOverflowError
org.hibernate.hql.internal.ast.tree.SqlNode.<init>(SqlNode.java:34)
sun.reflect.GeneratedConstructorAccessor36.newInstance(Unknown Source)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
java.lang.reflect.Constructor.newInstance(Constructor.java:526)
java.lang.Class.newInstance(Class.java:379)
org.hibernate.hql.internal.ast.SqlASTFactory.create(SqlASTFactory.java:256)
antlr.ASTFactory.create(ASTFactory.java:153)
antlr.ASTFactory.create(ASTFactory.java:186)
org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2018)
org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2026)
org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2026)

And so on....

like image 794
kamil.rak Avatar asked Apr 15 '15 08:04

kamil.rak


People also ask

Why StackOverflow error occurs?

A stack overflow is a type of buffer overflow error that occurs when a computer program tries to use more memory space in the call stack than has been allocated to that stack.

How to resolve StackOverflowError in java?

Solution. The simplest solution is to carefully inspect the stack trace and detect the repeating pattern of line numbers. These line numbers indicate the code that is being recursively called. Once you detect these lines, look for the terminating condition (base condition) for the recursive calls.

How do I Soft Delete in spring boot?

A common way to implement soft delete is to add a field that will indicate whether data has been deleted or not. This SQL command will permanently remove the product with id=1 from the table in the database. Note we added a new field called deleted.

How do I delete multiple records in JPA?

First of all you need to create a jpa query method that brings all records belong to id. After that you can do deleteAll() operation on List.


1 Answers

in your case, the delete query will be translated by JpaRepository to be looks like this.

delete from [table_name] where [criteria] = id or [criteria] = id (and so on...)

the jvm throws a stack overflow error because the HqlSqlBaseWalker is trying to search all the or (or basically the where criteria) statement

I guess, in your case, you could try to generate your own delete query and then execute it or you could try to split the data into few lists.

like image 117
kucing_terbang Avatar answered Sep 20 '22 13:09

kucing_terbang