SpringBoot Repository findAll zu viel Werte

Hallo zusammen,

hab in meinem Frontend eine DataTable mit Filtern:

Nun sollen in die Tabelle 500.000 Einträge geladen, das geht natürlich nicht auf einen Schlag.

Wie kann ich bewerkstelligen, dass :

a) immer nur 10, 20, 30 Entites geladen werden (Kann einen Paginator einbauen, dann geht der Filter aber nicht mehr)
b) die Filterfunktion aber dennoch erhalten bleibt

oder

c) nur die Daten geladen werden, die in die Tabelle kommen, mit einem KLick auf eine Zeile wird dann erst die komplette Entity geladen ( das wäre mir am liebsten, da es viele Associations gibt und das Laden entsprechend lange dauert)

Verstehe ich nicht - willst du clientseitig filtern? Mit Spring Data JPA kannst du Pagination auch auf alle anderen Queries anwenden. Die Queries müssen dann natürlich entsprechend den Filterkriterien gewählt werden.

Zur Option c: „halbe“ Entities laden macht keinen Sinn. Der Datentransfer ist nicht so teuer. Referenzen sollten natürlich (wo sinnvoll) lazy geladen werden. Solange die Daten aber nicht ausschließlich aus indizierten Werten bestehen, kann auch gleich die ganze Zeile geladen werden.

Ah sas geht also doch irgendwie ok danke dann muss ich mich da mal einlesen in den Paginator

Details findest du hier:
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.special-parameters
und hier:
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.limit-query-result

Danke euch, hab jetzt erstmal das Pageable eingebaut. Klappt auch soweit mit 10 Stück. Was ich aber jetzt nicht verstehe ist, wie soll der Filter auf die Werte filtern, die ja noch gar nicht aus der DB geladen sind, das wird auch gar nicht funktionieren wie ich mir das denke, sondern immer nur auf die, die geladen wurden.

Weiterhin kann ich mir nicht erklären, wie eine Sortierung ALLER Werte stattfinden soll, wenn es nur 10 geladen hat.

Kann mich jemand erleuchten bitte oder hat einen Tipp, wie ich mein Vorhaben umsetzen sollte? Aktuell sieht es so aus:

Wie oben schon geschrieben: wenn Sortierung und Filterung clientseitig passieren soll, geht kein Weg am Laden aller Entitäten vorbei.
Bei sovielen Einträgen macht das aber keinen Sinn. Lieber wird vom Browser ein asynchroner Request abgesetzt, der die Tabelle aktualisiert.

Serverseitige Filterung und Sortierung macht die Datenbank, bevor das limitierte Ergebnisset zurückgegeben wird anhand der gesamten Datenmenge unter Zuhilfenahme von Indizes.

Ok vielen Dank. Hab jetzt mal spasseshalber 1000 Einträge geladen, bekomme aber immer einen Broken Pipe Exception. Irgendwie wartet der client nicht auf die Antwort, hast du ne Idee was das sein könnte bzw wie ich dem vorbeugen könnte?

Ohne weitere Details zu der Exception kann ich nichts weiter beitragen.
Vielleicht liegt das Problem in der Systemkonfiguration beim Zugriff auf den SQL-Server, vielleicht aber auch ganz woanders.

Die gesamte Exception siehe unten. Der Service will wohl antwort senden, aber der Client hat schon die Verbindung eingestellt. Wie gesagt so bis 100 Einträge holen geht, alles wann länger als X Sekunden dauert geht nicht. Muss irgendein Timeout sein

org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:356) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.connector.OutputBuffer.flushByteBuffer(OutputBuffer.java:825) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:730) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:391) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:369) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at com.fasterxml.jackson.core.json.UTF8JsonGenerator._flushBuffer(UTF8JsonGenerator.java:2085) ~[jackson-core-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.core.json.UTF8JsonGenerator._writeStringSegment2(UTF8JsonGenerator.java:1400) ~[jackson-core-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.core.json.UTF8JsonGenerator._writeStringSegment(UTF8JsonGenerator.java:1347) ~[jackson-core-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.core.json.UTF8JsonGenerator.writeString(UTF8JsonGenerator.java:460) ~[jackson-core-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.ser.std.StringSerializer.serialize(StringSerializer.java:41) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:145) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:107) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.ser.std.ObjectArraySerializer.serializeContents(ObjectArraySerializer.java:249) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.ser.std.ObjectArraySerializer.serialize(ObjectArraySerializer.java:210) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.ser.std.ObjectArraySerializer.serialize(ObjectArraySerializer.java:22) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:400) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1392) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:913) ~[jackson-databind-2.9.5.jar:2.9.5]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:286) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:102) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:272) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:180) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:82) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:119) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) [spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866) [spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) [spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) [spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) [spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) [spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.31.jar:8.5.31]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_151]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_151]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.31.jar:8.5.31]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_151]
Caused by: java.io.IOException: Broken pipe
at sun.nio.ch.FileDispatcherImpl.write0(Native Method) ~[na:1.8.0_151]
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47) ~[na:1.8.0_151]
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93) ~[na:1.8.0_151]
at sun.nio.ch.IOUtil.write(IOUtil.java:65) ~[na:1.8.0_151]
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471) ~[na:1.8.0_151]
at org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:134) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.tomcat.util.net.NioBlockingSelector.write(NioBlockingSelector.java:101) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:157) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.doWrite(NioEndpoint.java:1276) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.tomcat.util.net.SocketWrapperBase.doWrite(SocketWrapperBase.java:670) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.tomcat.util.net.SocketWrapperBase.writeBlocking(SocketWrapperBase.java:450) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.tomcat.util.net.SocketWrapperBase.write(SocketWrapperBase.java:388) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.coyote.http11.Http11OutputBuffer$SocketOutputBuffer.doWrite(Http11OutputBuffer.java:623) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.coyote.http11.filters.ChunkedOutputFilter.doWrite(ChunkedOutputFilter.java:123) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.coyote.http11.Http11OutputBuffer.doWrite(Http11OutputBuffer.java:225) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.coyote.Response.doWrite(Response.java:541) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:351) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
… 79 common frames omitted

zuul.host.socket-timeout-millis=-1

Im Zuul Api Gateway war die Lösung.

Das hat scheinbar nicht auf die Response gewartet und einfach 200 OK als Antwort geschickt nach 10 Sekunden ohne Response

Ich mein ich hätte es schon mal geschrieben aber hier gerne aus gegebenen Anlass nochmal.

Deine genutzte Technik ist sehr gut. Die Wahl des TechnoStacks sehr gut. Ebenfalls finde ich es gut, dass du bestimmt Probleme auch hier i Forum diskutierst.

Und ich würde so gerne helfen, weil ich seit Jahren Fast die gleichen Komponenten Einsätze.

Schade nur, dass die Fragen so oberflächlich sind, dass man darauf nicht antworten kann. Und so wie deine Lösung so komplett von der Fragestellung losgelöst ist, ist für mich extrem frustrierend.

Die Leute hier lesen sich deine Probleme durch offerieren Hilfe. Investieren Zeit. Und du denkst, meinen geheimen Code darf keiner sehen. Denke beim nächsten mal darüber nach mehr relevante Informationen zu posten.

Da wären dir endlos viele Leute dankbar.

Gruß

Martin

1 „Gefällt mir“

Hi Martin,

wenn ich eine Frage wie diese habe, was soll ich da für einen Code posten? Muss ja erstmal das Problem erläutern, das Posten meines Repo-Codes wäre sinnlos, da er ja funktioniert mit 10 Einträgen aber nicht mit 1000. Somit kann es ja nicht wirklich am Code liegen. Werde beim nächsten mal aber versuchen mehr Infos raus zu rücken, das hat nichts, aber auch gar nichts mit geheimen Code zu tun! Ich darf es einfach nicht und daran halte ich mich.

Im Leben bin ich darauf gekommen, dass das API Gateway daran Schuld sein könnte. Aber die Fragestellung passt nicht wirklich zur Lösung, da geb ich Dir Recht. Werd es mal anpassen. und auf die BrokenPipe Exception bin ich auch erst lange nach dem Posten gekommen.

Guten Rutsch!

Edit: kann den Titel nicht ändern, vielleicht kann ein Mod den Titel anpassen auf “Spring Boot Broken Pipe bei REST Request”

Grundsätzlich noch ein Tipp: mit einem Debugger hättest du das Problem sehr schnell lokalisiert. Die Ursache einzugrenzen hilft auch bei einer schnellen Lösungsfindung.
Und wenn man dann doch nicht mehr weiter weiß, kann man recht konkret im Forum nach Hilfestellung fragen.

P.S. das Broken Pipe Problem ist erst in einem Folgebeitrag aufgetaucht und hatte mit der Ursprungsfrage nichts zu tun.

Ich hab es nicht mit dem Debugger gefunden, sonst hätte ich wohl hier nicht gefragt. Stimmt aber, hätte einen zweiten Thread auf machen können, nachdem das mit dem Paginator geklärt war.

Ich entschuldige mich aufrichtig und in aller Form. Reicht das jetzt oder soll ich noch persönlich jedem Danke sagen?!

Kein Grund, sich persönlich angegriffen zu fühlen. Es gab hier lediglich gut gemeinte Hinweise.
Noch zwei weitere Hinweise:

  1. Bei einem Posting ist es immer sinnvoll zu schreiben, was man schon alles versucht hat. Das erspart dem Helfer unnötige Mühe.
  2. Lerne Kritikfähigkeit.

Keine sorge, ich fühle mich nicht angegriffen. Das war ironisch. Ich denke hier ist alles gesagt. Guten Rutsch :partying_face: