JPA --- @ManyToOne


#1

Hi!

Es geht um JPA2.1 mit EclipseLink und einer Entity mit einer ManyToOne Beziehung.

@Entity public class Bestellung implements Serializable { ... @JoinColumn(name = "LieferantNr", referencedColumnName = "LieferantNr", insertable=false, updatable=false) @ManyToOne private Lieferant lieferant;

dazu diese Einfache Abfrage

... ... em.createQuery("select b from Bestellung b");

Mein Problem ist, dass beim Ausführen der o.g. Abfrage je Bestellung ein Query abgeschickt wird, um die LieferantenInfo zu holen. Das dauert leider etwas lange.

Ich hätte erwartet, dass JPA eine gejointe Abfrage abschickt und das Thema in einem Zug abwickelt.

Mache ich etwas falsch oder ist das vom Erfinder so gedacht?

Danke

Daniel


#2

Sieht so aus, als wäre genau dafür @BatchFetch vorgesehen: http://www.eclipse.org/eclipselink/documentation/2.5/jpa/extensions/a_batchfetch.htm

Aber ob das deine Version schon unterstützt…


#3

Ich habe die letzten Jahre zwar nur noch mit der Criteria API (oder gleich mit QueryDSL gearbeitet), aber du hast zwei Möglichkeiten:

  • Du kannst wie von Landei beschrieben @BatchFetch oder @JoinFetch benutzen und das Fetch Verhalten an der Entity markieren
  • Du kannst explizit beim Fetch die Joins mit angeben, um im Query zu signalisieren was alles geladen werden soll

Hast du als Fetch Mechanismus denn Eager oder Lazy angegeben? Das kann beim Verhalten, wie JPA die Querys erstellt auch eine Rolle spielen


#4

Wir arbeiten täglich mit JPA in unserem Projekt. Mit den Query Hints haben wir gute Erfahrungen gemacht. Damit kann man einzelne Queries optimieren, was meistens zu besseren Resultaten führt als allgemeine Optimierungen.

Was wir auch gelernt haben: JPA und Performance sind zwei Welten die sich nicht mögen. JPA liebt es kleine Stücklein nachzuladen, und man muss jedes einzelne Query untersuchen um eine halbwegs brauchbare Anwendung zu kriegen. Der Einbau von Caches kann helfen. Wir haben bei unserem Server auch noch JOOQ eingebaut, um direkter mit der DB zu sprechen (mit dem Nachteil, dass man selbst eine Abstraktionsschicht zwischen DB und Businesslogik schreiben muss. Aber der Aufwand ist es uns Wert. Mittlerweile denken wir, dass ziemlich jede Lösung besser ist, als JPA).


#5

Danke euch! :slight_smile: Der BatchFetch hat sehr geholfen.

JOOQ scheint ganz toll zu sein. Das schau ich mir mal an.


#6

Beni, ich stimme dir im Großen und Ganzen zu. Das gefährliche an JPA ist, dass es “Einfachheit” verspricht, wo keine sein kann. Relationale Strukturen in Objekte herunterzubrechen ist hart, und da kann auch ein ORM nicht helfen. Wenn ich mir am Ende die fertige Anwendung anschaue, habe ich meistens pro View und pro Listenabfrage und pro Entity ein eigenes Query, bei welchem ich JPA genau sage, wie es auf die DB zuzugreifen hat, wie viel es zu laden hat und (teilweise) auch wie es zu joinen hat.

JOOQ hat mich in der Vergangenheit immer wieder mal interessiert, aber 90% unserer Kunden benutzen Oracle, und irgendwie möchte die Lizenzgebühren keiner zahlen :confused: