2015-04-15 2 views
3

У меня есть вопрос об удалении элементов из db с помощью deleteInBatch. У меня есть объект А, имеющий список объектов B, как:Spring JPA deleteInBatch вызывает StackOverflow

class A { 
private List <B>; 
} 

список содержит более 7K элементов. Итак, теперь я должен удалить A и все его элементы. Я попытался с помощью deleteInBatch, но я получаю

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

Удаление элементов с sipmle удаления метод работает, но это занимает больше 5 минут. Мой код удаления:

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

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

Есть хорошее решение, чтобы ускорить процесс удаления или как изменить таким образом, чтобы deleteinbatch не принимать все гибернации стек - без увеличения его?

Полный 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) 

И так далее ...

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) 

И так далее ....

+0

Вы могли бы разместить полный стек? –

ответ

4

в вашем случае удаления запроса будет переведен JpaRepository будет выглядеть следующим образом.

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

виртуальная машина генерирует ошибку переполнения стека, потому что HqlSqlBaseWalker пытается найти все или (или в основном те where критерии) заявление

я думаю, в вашем случае, вы могли бы попытаться создать ваш собственный запрос на удаление, а затем выполнить его, или вы можете попытаться разбить данные на несколько списков.

+0

Итак, вы имеете в виду, что «пакет» на самом деле не создает JACK-пакет JQBC? Это довольно плохая новость для любого администратора базы данных, который настраивает кеширование кэшей ... –

+1

@LukasEder хорошо, я думаю, что проблема кроется в «серийном» терминах здесь. Я имею в виду, что мы обычно ожидаем в этом случае, так это то, что спящий режим будет разделять данные и попытаться вставить эти данные, как один раз, для каждых 100 данных. но, если вы читаете в api doc, в нем упоминается, что функция действительно создаст один «запрос». поэтому, я думаю, что урок здесь - мы должны дважды подумать, чтобы назвать наш публичный api;) –

+0

Да, я создал свой собственный запрос на удаление. Процесс занял 3 минуты, но я создал индекс на ключе, и он работает хорошо. Спасибо :) – kamirru

0

У меня такая же проблема (java.lang.StackOverflowError) и создан метод с моим собственным запросом на удаление, например. deleteByIdAndYear (...), чтобы избежать этого.

Смежные вопросы