# Select * from bringt keine Rückgabe



## OnDemand (10. Mai 2020)

Hallo zusammen,

etwas sehr komisch kommt mir grad unter. Ich habe eine Methode in welcher  ich  einen `SELECT * FROM bla where active= true and valid = false`
Allerdings verrennt sich die Abfrage und bleibt irgendwie hängen, es geht einfach nix weiter, keine Fehlermeldung nix. Es sind gut 4000 Datensätze und 15 cols also nicht so irre viel find ich. Indexe liegen auf der id, active und valid. Kann es sein dass man auf boolean keinen Index setzen kann/Sollte? Aber auch wenn ich nur `SELECT * FROM bla` aufrufe, kommt auch nix.

Rufe ich es in einem Client wie Datagrip oder Heidisql auf, kommt ein Ergebnis und zwar binnen paar ms wie man es auch erwartet.

Hat jemand ne Idee wie ich da irgendwas Debugger kann DB seitig?


----------



## mrBrown (10. Mai 2020)

NicoDeluxe hat gesagt.:


> Rufe ich es in einem Client wie Datagrip oder Heidisql auf, kommt ein Ergebnis und zwar binnen paar ms wie man es auch erwartet.


Und wo führst du das aus, wenn kein Ergebnis kommt?


----------



## OnDemand (10. Mai 2020)

In meinem Code über Spring Boot Repository. Kann das irgendwas mit den Prepared Statements zu tun haben? Ich schließe die nicht, weil sie wieder ein Hikari Pool wandern.

Hab grad mal die Datensätze angepasst, sodass die List mit findAll() nur 10 Datensätze holt, die kommen auch. Also muss es irgendwas in Richtung lahmarschige Verbindung sein oder? Warum gehts dann aber mit Heidi  Co.. sehr komisch 

Dummycode :

```
@PostMapping("/update/{herstellerId}")
    @Transactional
    public void update(@PathVariable int herstellerId) {

           Session hibernateSession = em.unwrap(Session.class);
            hibernateSession.doWork(new org.hibernate.jdbc.Work() {
                @Override
                public void execute(Connection connection) {
                PreparedStatement ps = connection.prepareStatement("update ....");
               //PS befüllen
               ps.addBatch();
               ps.executeBatch(); //läuft auch durch

   //Testweise hier mal ein Aufruf der alle 4000 Datensätze holt, ohne Ergebnis. Bleibt hier einfach hängen
   List<Auto> autos = autoRepository.findAll();
   //irgendwas mit der List machen

        }
    }
}
```


----------



## mrBrown (10. Mai 2020)

NicoDeluxe hat gesagt.:


> Kann das irgendwas mit den Prepared Statements zu tun haben? Ich schließe die nicht, weil sie wieder ein Hikari Pool wandern.


Schließt du sie nicht, damit sie nicht in den Pool wandern, oder schließt du sie nicht, weil sie dMn allein in den Pool wandern?



NicoDeluxe hat gesagt.:


> Also muss es irgendwas in Richtung lahmarschige Verbindung sein oder?


Log einfach mal, was Hibernate und der DB-Driver so machen.



NicoDeluxe hat gesagt.:


> Dummycode :


Auffällig ist daran das nicht geschlossene PreparedStatement, das findAll innerhalb von execute und überhaupt die Nutzung von hibernateSession.doWork.
Aber keine Ahnung was davon irgendwas mit dem Fehler zu tun hat oder was dem Dummycode geschuldet ist...


----------



## OnDemand (11. Mai 2020)

das findAll ist außerhalb des doWork.

Hibernates doWork nutze ich da, weil ich viele viele Daten Updaten muss. Mit HIbernate dauert das ewig, mit dem PrepearedStatement 5 Sekunden.

Wenn ich das PS mit .close() Schließe, geht danach gar nix mehr, die Verbindung ist w wie weg und ich bekomme eine Exception dass keine Verbindung gibt, also gehe ich davon aus, dass sich Hibernate um die Verbindung kümmert. 

Wie gesagt funktioniert das Abholen mit findAll() sobald es nur ein paar wenige Datensätze sind. Die 4000 schafft es nich, ich sehe auch in der DB mit show processlist, dass da immer mal ein Prozess hängt mit Sending Data. Ich hab die doofe Vermutung, dass die DB irgendwo falsch konfiguriert ist.


----------



## LimDul (11. Mai 2020)

Klappt es denn, wenn du als erstes, nach dem Aufbauen der Verbindung ein findAll machst? Also mal ohne das Prepared Statement davor auszuführen? Nutzt du irgendwo Multithreading?

Ansonsten wie empfohlen mal den Log Level von Hibernate hochdrehen - das Problem ist schon seltsam.


----------



## OnDemand (11. Mai 2020)

Auch vor dem doWork kommt es nur, wenn wenige Datensätze geladen werden müssen.

ich bekomme heute einen neuen Serverfür die DB mal sehen wir es mit dem läuft.

ich vermute dass die dB Tabelleschlecht aufgebaut ist. Notfalls hole ich mirdie die Werte mittels Aufzählung statt mit Stern

also SELECT id, bla, blu, FROM table. Das geht komischerweise


----------



## mrBrown (11. Mai 2020)

NicoDeluxe hat gesagt.:


> das findAll ist außerhalb des doWork.


In dem Code halt nicht 



NicoDeluxe hat gesagt.:


> Hibernates doWork nutze ich da, weil ich viele viele Daten Updaten muss. Mit HIbernate dauert das ewig, mit dem PrepearedStatement 5 Sekunden.


Dafür sind aber keine solchen Konstrukte nötig, das kann man direkt mit zB JdbcTemplate lösen.
(Und auch Spring-Data-Repositorys unterstützen Batching, man muss es nur aktivieren)



NicoDeluxe hat gesagt.:


> Wenn ich das PS mit .close() Schließe, geht danach gar nix mehr, die Verbindung ist w wie weg und ich bekomme eine Exception dass keine Verbindung gibt, also gehe ich davon aus, dass sich Hibernate um die Verbindung kümmert.


Ja, aber das Statement kann (und sollte) man üblicherweise schließen. Wenn man nicht grad sehr merkwürdig Dinge macht, klappt das völlig Problemlos.



NicoDeluxe hat gesagt.:


> Notfalls hole ich mirdie die Werte mittels Aufzählung statt mit Stern
> 
> also SELECT id, bla, blu, FROM table. Das geht komischerweise


Du nutzt doch `autoRepository.findAll` - wo hast du da eine Query mit "Stern"?


----------



## OnDemand (11. Mai 2020)

das `findAll()` verhält sich in beiden Varianten gleich, egal ob in oder außerhalb der doWork, auch in einer völlig anderen Methode tut es nix, sobald viele Daten geladen werden.

Öh wie kann ich Updates mit Batch ausführen? Vielleicht wäre das wirklich eine bessere Alternative.

Wenn ich das PS `close()`, geht es nicht in den Connection Pool zurück, daher kann ich es nicht schließen. Da muss sich Hibernate drum kümmern (so auch die weitläufige Zustimmung auf Stackowerflow). mit `executeBatch()` wird die Connection wieder released undgeht in den Pool zurück. Aber kann damit ja auch nix zu tun haben, da es vor der `doWork()` auch nicht geht

Mein Query liegt in einem Repository das CrudRepository implementiert, wie alle anderen Queries die ich so nutze. 
Auch wenn ich es nicht mit einem Native Query mache, sondern JPQL (?) macht es genau das selbe. 

Ich werde später mal mit dem Datenbankmensch reden, vielleicht hat der ne Idee dass da DB Seitig was nicht stimmt oder suboptimal konfiguriert ist.


----------



## mrBrown (11. Mai 2020)

NicoDeluxe hat gesagt.:


> Öh wie kann ich Updates mit Batch ausführen? Vielleicht wäre das wirklich eine bessere Alternative.


Per Data-JPA: https://www.baeldung.com/spring-data-jpa-batch-inserts
Mit JdbcTemplate: https://docs.spring.io/spring/docs/...k-reference/html/jdbc.html#jdbc-advanced-jdbc



NicoDeluxe hat gesagt.:


> Wenn ich das PS `close()`, geht es nicht in den Connection Pool zurück, daher kann ich es nicht schließen. Da muss sich Hibernate drum kümmern (so auch die weitläufige Zustimmung auf Stackowerflow). mit `executeBatch()` wird die Connection wieder released undgeht in den Pool zurück.


Kann es sein, dass du da grad Connection und PreparedStatement durcheinander wirfst? Connection sollet man nicht schließen, die wird ja auch von außen rein gereicht. PS erstellt man selbst, sollte man dann auch schließen, wird auch in der Hibernate-Doku so gemacht. Wenn ein Schließen eines PS die Connection "zerstört", liegt da höchstwahrscheinlich irgendwas anderes im Argen.

Das muss nichts mit diesem Fehler zu tun haben, irgendwas läuft da dann aber unsauber.



NicoDeluxe hat gesagt.:


> Mein Query liegt in einem Repository das CrudRepository implementiert, wie alle anderen Queries die ich so nutze.
> Auch wenn ich es nicht mit einem Native Query mache, sondern JPQL (?) macht es genau das selbe.


Und deine native Query war ein "Select *", und ein explizites Statement löst das Problem?

Was für Columns sind in der Datenbank zu finden? Wie sieht die Entity aus? Ich würde da irgendwelche Felder vermuten, die das ganze langsam machen, die in deinem expliziten Statement (unbeabsichtigt) fehlten.


----------



## LimDul (11. Mai 2020)

Mal ins blaue rein - das select geht wirklich auf eine Tabelle und nicht zufällig eine View? (Ja, es steht so im Beitrag, aber hinterfragen kann man es trotzdem mal)


----------



## OnDemand (11. Mai 2020)

Danke, JDBC Template komm ich nicht ran, da kam immer eine Fehlermeldung dass es eine Bean vom Typ DataSource braucht, da ich aber eine tenante DB Verwaltung mit einem Pool je Tenant hab, hab ich das nicht hinbekommen.

Ich würde behaupten, ich habe ps.close() gemacht, werd ich aber nochmal prüfen, vielleicht hab ich es wirklich mit Connection verwechselt. Dann werde ich das natürlich schließen. Wird aber nicht zur Lösung beitragen, aber evtl. späteren Problemen vorbeugen.

In der Tabelle sind nur Spalten mit int, varchar, bit und 2 Spalten vom Typ Date, insgesamt 34. Indexe liegen auf der ID sowie auf den beiden Bit-Spalten die in der Where - Clausel abgefragt werden.

@LimDul 
ein Select auf eine View? Weiß nicht mal was das ist  die geht auf die Tabelle (mein lokaler Client bringt auch Ergebnis also auch korrekt der Query)


----------



## mrBrown (11. Mai 2020)

NicoDeluxe hat gesagt.:


> In der Tabelle sind nur Spalten mit int, varchar, bit und 2 Spalten vom Typ Date, insgesamt 34. Indexe liegen auf der ID sowie auf den beiden Bit-Spalten die in der Where - Clausel abgefragt werden.


Und wie sieht die Entity auf Java-Seite aus?


----------



## OnDemand (11. Mai 2020)

Öhm was genau meinst? Ein paar OneToOne Relations und rest keine Relation (Grad keinen Code zur Hand)


----------



## mrBrown (11. Mai 2020)

NicoDeluxe hat gesagt.:


> Öhm was genau meinst? Ein paar OneToOne Relations und rest keine Relation (Grad keinen Code zur Hand)


zB Relationen. OneToOne ist Eager, möglicherweise hast du da ein N+1 Problem...


----------



## OnDemand (11. Mai 2020)

Ah interessante Spur, aber das doch eigentlich egal bei einem Native Query, der holt mir ja dann die ID statt des Objektes welches da an der Relation hängt?
OK, bei findAll() würde das Sinn machen, aber beim nativen Select Query wäre das doch wurst oder?


----------



## thecain (11. Mai 2020)

Ich vermute du hast irgendwas komisches zusammengewurstelt, dass nicht wirklich Spring Standard/best Practice ist. Jetzt passt etwas nicht zusammen oder ist falsch implementiert.

Am einfachsten postest du mal deinen richtigen Code oder machst ein kleines ausführbares Beispiel, bei dem der Fehler auch auftritt. Im Dummycode von dir stimmt ja nichtmal die Klammerung, das hilft nicht viel beim solche Fehler finden.


----------



## mrBrown (11. Mai 2020)

NicoDeluxe hat gesagt.:


> Ah interessante Spur, aber das doch eigentlich egal bei einem Native Query, der holt mir ja dann die ID statt des Objektes welches da an der Relation hängt?


Das ganze mappst du dann aber mit Hibernate, und auch das kann in `@OneToOne User owner` nicht einfach eine "17" schreiben.


----------



## OnDemand (11. Mai 2020)

Achso ok ja stimmt, macht Sinn. Hier mal der Query wo grad Ärger macht.
Auf dem neuen Server übrigens das Gleiche Problem.

Und so sieht es in der processlist aus


`@Query(value = "SELECT * FROM product where xx=true AND yy= :zz", nativeQuery = true)
List<Product> getProducts(boolean zz);`

Und hier die Entity (Getter Setter und die einfachen Datentypen hab ich entfernt)

```
@Entity
@DynamicUpdate
@Table(name = "product", indexes = {@Index(name = "products_sku_index", columnList = "products_sku")})
@NamedQuery(name = "Product.findAll", query = "SELECT p FROM Product p")
public class Product implements Serializable {
    private static final long serialVersionUID = 1;

    /**
     * ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    @Column(name = "manufacturer_id")
    private int manufacturer;

    @Column(name = "vk_price")
    double vkPrice = 0.00;

    @Column(name = "xx")
    boolean xx;

    @Column(name = "yy")
    boolean yy;

    @OneToMany(orphanRemoval = true, cascade = {CascadeType.ALL})
    @LazyCollection(LazyCollectionOption.FALSE)
    @JoinColumn(name = "product_id")
    private List<ProductsImage> productImages = new ArrayList<>();


    @OneToOne(cascade = {CascadeType.ALL})
    @JoinColumn(name = "products_codes_id")
    @LazyCollection(LazyCollectionOption.FALSE)
    private ProductsCodes productsCodes;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "packaging_unit_id")
    private PackagingUnit packagingUnit;

    @ManyToOne
    @JoinColumn(name = "tax_class_id")
    private TaxClass taxClass;
}
```


----------



## mrBrown (11. Mai 2020)

Alle deine Beziehungen sind EAGER, kein Wunder dass es bei 4000 Elementen ewig dauert...


Ich würde generell auch sowohl auf * als auch auf die Native Query verzichten, ersteres ist nie guter Stil und eine native query brauchst du dort nicht, auch wenn’s für dieses Problem egal ist.


----------



## OnDemand (11. Mai 2020)

ne hier macht der Select * keinen sinn, hast Recht. Was statt EAGER?
Wir könnte ich ein product holen, mit nur der ID, name und preis zb?

Geht nur mit einem Object Array oder gibts da auch eine schönere Art?


----------



## mrBrown (11. Mai 2020)

NicoDeluxe hat gesagt.:


> ne hier macht der Select * keinen sinn


Weniger „hier“ als vielmehr „immer“ 



NicoDeluxe hat gesagt.:


> Was statt EAGER?


Die einzig andere Möglichkeit, die es gibt? So viel Auswahl hat man da ja nicht 


Und schalte wenigstens für‘s Debugging das Loggen der sql-Statements ein...


----------



## OnDemand (11. Mai 2020)

Über das Thema * oder nicht hab ich gestern auch wieder einiges gelesen beim recherchieren. Gibt da zwei Lager  die * und die Anti* Fraktion 

LAZY meinste? Ich dachte, dass ist die langsamere Art, weil alle unterliegenden Objekte nachgeladen müssten oder hab ich da was total durcheinander gebracht


----------



## mrBrown (11. Mai 2020)

NicoDeluxe hat gesagt.:


> Gibt da zwei Lager  die * und die Anti* Fraktion


Ich kenn da nur die „Mach es vernünftig“ und die „Trololololo“-Fraktion.



NicoDeluxe hat gesagt.:


> LAZY meinste? Ich dachte, dass ist die langsamere Art, weil alle unterliegenden Objekte nachgeladen müssten oder hab ich da was total durcheinander gebracht


Mit eager werden alle Relationen sofort geladen, mit lazy erst dann, wenn sie benötigt werden.
Für die 4000 Autos bedeutet ersteres direkt 16001 Querys, auch wenn du nur deren ID wissen willst.
Mit lazy wäre das nur eine Query.


----------



## LimDul (11. Mai 2020)

NicoDeluxe hat gesagt.:


> Über das Thema * oder nicht hab ich gestern auch wieder einiges gelesen beim recherchieren. Gibt da zwei Lager  die * und die Anti* Fraktion
> 
> LAZY meinste? Ich dachte, dass ist die langsamere Art, weil alle unterliegenden Objekte nachgeladen müssten oder hab ich da was total durcheinander gebracht


EAGER=Die Daten werden sofort geladen. 
LAZY=Die Daten werden beim Zugriff nachgeladen.

EAGER hat Vorteile:
- Wenn die Datenmengen klein sind
- Wenn auf die Daten zu nahezu 100% eh zugegriffen werden muss


LAZY hat Vorteile:
- Wenn auf die Daten im weiteren Verlauf nicht immer zugegriffen wird (oder nicht immer auf alle gleichzeitig)

Dadurch das deine beiden OneToMany Beziehungen EAGER sind werden die komplett geladen. je nach dem, wie das aussieht, werden da ziemlich viele oder ziemlich große SQL Statements (Kreuzprodukte) generiert.


----------



## mrBrown (11. Mai 2020)

LimDul hat gesagt.:


> Dadurch das deine beiden OneToMany Beziehungen EAGER sind werden die komplett geladen. je nach dem, wie das aussieht, werden da ziemlich viele oder ziemlich große SQL Statements (Kreuzprodukte) generiert.


Sind ja sogar 4 Relationen, die EAGER sind, dürften damit 4 zusätzliche Querys pro Produkt sein.


----------



## thecain (11. Mai 2020)

Wenn du wirklich alle Attribute die im moment EAGER geleaden werden benötigst, dann hilft auch Lazy nicht weiter. Dann benötigst du ein FETCH JOIN im Query.

Eigentlich solltest du die Querys zum Nachladen sehen, wenn du das Query Logging aktivierst. Das Query Logging einzuschalten macht sowieso Sinn. Beim Debuggen von solchen Fehlern


----------



## OnDemand (11. Mai 2020)

Ahaaaaa ok und wie würde ich „triggern“ dass ich ein angehängtes Objekt möchte?


----------



## mrBrown (11. Mai 2020)

NicoDeluxe hat gesagt.:


> Ahaaaaa ok und wie würde ich „triggern“ dass ich ein angehängtes Objekt möchte?



Passiert automatisch


----------



## thecain (11. Mai 2020)

Ich denke es macht Sinn für dich, dich mal tiefer in das Thema einzulesen. Das macht auf jeden Fall Sinn, wenn du JPA/Hibernate weiter verwenden wirst.

Ich kann es eigtl. nur schlechter erklären, als es da steht.

Hier zwei Artikel:








						N+1 query problem with JPA and Hibernate - Vlad Mihalcea
					

Learn what the N+1 query problem is and how you can avoid it when using SQL, JPA, or Hibernate for both EAGER and LAZY associations.




					vladmihalcea.com
				











						A beginner's guide to Hibernate fetching strategies - Vlad Mihalcea
					

Introduction When it comes to working with an ORM tool, everybody acknowledges the importance of database design and Entity-to-Table mapping. These aspects get a lot of attention, while things like fetching strategy might be simply put-off. In my opinion, the entity fetching strategy shouldn’t...




					vladmihalcea.com
				




Zum Thema JPA bist du allgemein im Blog von Vlad Mihalcea sehr gut aufgehoben


----------



## OnDemand (11. Mai 2020)

Danke hab schon ein buch da 😂 müsste es mal benutzen.

heissr grob gesagt ich hole ein product mit lazy und sobald ich die imagelist brauche, werden die nachgeladen?


----------



## OnDemand (11. Mai 2020)

Ok, wow. Hab nun mal getestet, das laden dauert 13s (ein teil sicher meiner Leitung geschuldet) wenn ich es auf Lazy anpasse, bin ich im ms Bereich. ABER nun verstehe ich folgendes nicht so ganz:

Ich habe eine Tabelle in der View und möchte da alle Produkte anzeigen (Paginator ist eingebaut) es lädt nun 25 Artikel inkl. Bilder usw. . Klickt man nun auf ein Produkt wird das aus dem Speicher geladen und ich kann direkt alle Bilder präsentieren. 

Wenn ich das nun Lazy lade, hab ich die Bilder nicht. Wie komme ich nun an die Bilder ran? Extra Abfrage indem ich die Bilder seperat abfrage? Anders gehts ja nich oder bin ich auf dem Holzweg?


----------



## mrBrown (11. Mai 2020)

Kommt auf dein Design an, selbst machen muss man nicht wirklich irgendwas. Wenn man Best Practices folgt/nicht irgendwelche merkwürdigen Sachen macht klappt das "Out of the box" und man merkt keinen Unterschied in der Nutzung.

Wie ist die View umgesetzt, Serverseitig?
Werden die Entities direkt in der View genutzt oder werden für die View passende Objekt genutzt und zwischen Entity und ViewModel gemappt?


----------



## OnDemand (11. Mai 2020)

Das Frontend ist auf JSF also serverseitig, die Entitäten werden ohne extra Viewmodel genutzt, aber nicht wirklich direkt aus der DB.
Das Frontend ist aber ein seperater Service, welcher per REST den "product-Service" anfragt und die Produkte bekommt. Und schon haben wir ein Problem wie ich vermute


----------



## mrBrown (11. Mai 2020)

NicoDeluxe hat gesagt.:


> Und schon haben wir ein Problem wie ich vermute


Nö, designe dein Rest-Model passend, mappe die Entitäten auf das Model und das sollte alles klappen.


----------



## OnDemand (11. Mai 2020)

Hmm hast du irgendwie irgendwo ein Beispiel? Oder ein Stichwort nach dem ich googlen kann?


----------



## mrBrown (11. Mai 2020)

DTO?


----------



## OnDemand (11. Mai 2020)

Ah  😎 danke


----------



## OnDemand (12. Mai 2020)

Gar nicht so einfach da einen Einstieg zu finden  aberliest sich, als wäre das eine Lösung


----------



## mrBrown (12. Mai 2020)

NicoDeluxe hat gesagt.:


> Gar nicht so einfach da einen Einstieg zu finden


Moment, was guckst du dir grad an?


----------



## OnDemand (12. Mai 2020)

DTO Gedöns mit nachladen tralala


----------



## mrBrown (12. Mai 2020)

Alles was du brauchst sind nur ganz einfache Klassen:


```
class ImageDto {
    String name;

    static ImageDto fromImage(Image image) {
        var dto = new ImageDto;
        dto.name = image.getName();
        return dto;
    }
}

class ProductDto {
    String name;
    List<ImageDto> images;

    static ProductDto fromProduct(Product product) {
        var dto = new ProductDto;
        dto.name = product.getName();
        dto.images = product.getImages().stream().map(ImageDto::fromImage).collect(toList()));
        return dto;
    }
}
```

und dann im Controller mappen und zurückgeben:


```
@GetMapping
List<ProductDto> getProducts() {
    var products = productRepo.findAll(); //
    return products.stream().map(ProductDto::fromProduct).collect(toList()));   
}
```


----------



## OnDemand (12. Mai 2020)

oO das wars?? Uh die Schreibweise ist Java 8 oder mit Streams irgendwas kann das sein? Damit hab ich mich noch gar nicht befasst


----------



## mrBrown (12. Mai 2020)

NicoDeluxe hat gesagt.:


> das wars??


Ja, an was dachtest du denn?



NicoDeluxe hat gesagt.:


> Uh die Schreibweise ist Java 8 oder mit Streams irgendwas kann das sein? Damit hab ich mich noch gar nicht befasst


Ja, kann man aber auch Problemlos durch einfache schleifen ersetzen


----------



## OnDemand (12. Mai 2020)

Glaub ich hab zu kompliziert gedacht., das muss ich jetzt erstmal verinnerlichen. 

Wenn ich jetzt eine List mit dem ProductDto lade, sind die Images dann nicht drin?


----------



## OnDemand (12. Mai 2020)

Nu hab ich das mal eingebaut zum testen. Hab ich das richtig verstanden, dass ich nun je nach Bedarf ein DTO erstelle?

Für meine Ansicht der Tabelle in der alle Produkte aufgelistet werden, brauch ich ein DTO mit Artikelnummer, Name, Preis. Wenn jemand auf ein Produkt klickt, hole ich wieder ein anderes DTO mit anderen Details. Ist das so sinngemäß erstmal richtig?

Aber es holt trotzdem alle Produkte raus, laut debug log sendet es je Produkt + Image ein Select


----------



## mrBrown (12. Mai 2020)

NicoDeluxe hat gesagt.:


> Für meine Ansicht der Tabelle in der alle Produkte aufgelistet werden, brauch ich ein DTO mit Artikelnummer, Name, Preis. Wenn jemand auf ein Produkt klickt, hole ich wieder ein anderes DTO mit anderen Details. Ist das so sinngemäß erstmal richtig?


Ja, kann man so machen.

(Bei REST wären aber zwei getrennte Endpunkte für Produkte und Bilder üblicher, scheinst du aber vorher auch nicht so gehandhabt zu haben-)



NicoDeluxe hat gesagt.:


> Aber es holt trotzdem alle Produkte raus, laut debug log sendet es je Produkt + Image ein Select


Ja was erwartest du denn bei einem findAll und einem Zugriff auf die Bilder eines jeden Produkts?

Wenn du nur 20 brauchst solltest du auch nur 20 laden, wenn du die Bilder nicht brauchst solltest du die Bilder einfach ignorieren.


----------



## OnDemand (12. Mai 2020)

Ah durch das LAZY loading, werden die Collections nicht mitgeladen und dadurch wirds schneller. Verstehe so langsam Erst wenn ich das DTO mit den Images anfordere, werden auch die ImageCollections geladen. Puh da muss ich aber einiges umbauen


----------



## LimDul (12. Mai 2020)

Willkommen in den Untiefen von JPA  Du hast jetzt die zweite Stufe erreicht. Am Anfang freut man sich, dass man mittels JPA alles schön weg von der Datenbank abstrahiert bekommt und sich keinen Kopf drum machen muss. Es reicht Java Code zu schreiben.

Und irgendwann - an dem Punkt bist du jetzt - stellt man fest, dass sobald es um Massendaten, große Listen oder komplexe Abfragen gebt, man sich doch Gedanken machen, was da eigentlich auf der Datenbank passiert.


----------



## OnDemand (12. Mai 2020)

🤯 hab ich jetzt das nächste Level erreicht? Wie toll 🥺
Dann will ich nicht wissen, was der Endgegner ist haha.

Danke für die tolle Unterstützung @mrBrown, @LimDul 
War ja mal ein netter Thread, sonst ist man von Foren meist andere Umgangsformen gewohnt 👹


----------

