Eclipselink JoinFetch – man muss wissen, was man tut


Umgebung

  • JBoss 6
  • Eclipselink 2.5.2
  • EE 5

Eine Möglichkeit das 1:n Problem bei JPA Zugriffen zu lösen ist es, die abhängigen Werte einer Entität in einer Abfrage von der Datenbank zu bekommen. Hierfür bietet Eclipselink die Annotation @JoinFetch.

@Entity
public class Text2Translate extends Serializable {
...
@OneToMany(cascade = CascadeType.ALL, mappedBy = "...", fetch = FetchType.EAGER)
@JoinFetch(value = JoinFetchType.OUTER)
private List<Translation> translations = new ArrayList<Translation>();
…
}

Mit Hilfe dieser Annotation wurde in diesem Fall die Liste der Übersetzungen per left-join an die Objekte von der Klasse Text2Translate gebunden. Somit entfallen die n einzelnen Zugriffe auf die Datenbank, die beim Nachladen jeder einzelnen Übersetzung entstehen. Die Entität Übersetzung hat ein String Attribut Sprache, in dem Werte wie DE, ESP usw stehen. Eine Abfrage nach Entitäten mit einer Übersetzung in Deutsch könnte also wie folgt aussehen

SELECT x FROM Text2Translate x JOIN x.translations translation WHERE translation.language = ‘DE‘

Aber Achtung

Dies Anfrage liefert unvollständige Objekte. Übersetzungen einer andern Sprache als Deutsch werden nicht mit ausgelesen. Dies liegt daran, dass eine Abfrage an die DB gestellt und mit dem auf die Sprache gefilterten Ergebnis die Obejkte erzeugt werden. Da andere Sprachen nicht abgefragt werden, sind sie auch nicht in den erstellten Objekten. Würde die Abfrage ohne die @JoinFetch in der Entität erstellt, würde der JPA-Provider nur die Text2Translate Basisobjekte in der ersten Abfrage erhalten und dann über den PK alle Übersetzungen nachladen und somit vollständige Objekte erzeugen.

Ergebnis

@JoinFetch kann erhebliche Performance Gewinne bringen, man muss aber sehr genau aufpassen, welche Abfragen gestellt werden.

Du hast Fragen oder Anmerkungen? Kontakt: arndt@schoenb.de

,