{"id":134,"date":"2016-07-01T12:21:49","date_gmt":"2016-07-01T10:21:49","guid":{"rendered":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/?p=134"},"modified":"2022-12-04T12:22:10","modified_gmt":"2022-12-04T11:22:10","slug":"eclipselink-joinfetch-man-muss-wissen-was-man-tut","status":"publish","type":"post","link":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/?p=134","title":{"rendered":"Eclipselink JoinFetch \u2013 man muss wissen, was man tut"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Umgebung<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>JBoss 6<\/li>\n\n\n\n<li>Eclipselink 2.5.2<\/li>\n\n\n\n<li>EE 5<\/li>\n<\/ul>\n\n\n\n<p>Eine M\u00f6glichkeit das 1:n Problem bei JPA Zugriffen zu l\u00f6sen ist es, die abh\u00e4ngigen Werte einer Entit\u00e4t in einer Abfrage von der Datenbank zu bekommen. Hierf\u00fcr bietet Eclipselink die Annotation @JoinFetch.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">@Entity\npublic class Text2Translate extends Serializable {\n...\n@OneToMany(cascade = CascadeType.ALL, mappedBy = \"...\", fetch = FetchType.EAGER)\n@JoinFetch(value = JoinFetchType.OUTER)\nprivate List&lt;Translation&gt; translations = new ArrayList&lt;Translation&gt;();\n\u2026\n}\n<\/pre>\n\n\n\n<p>Mit Hilfe dieser Annotation wurde in diesem Fall die Liste der \u00dcbersetzungen 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 \u00dcbersetzung entstehen. Die Entit\u00e4t \u00dcbersetzung hat ein String Attribut Sprache, in dem Werte wie DE, ESP usw stehen. Eine Abfrage nach Entit\u00e4ten mit einer \u00dcbersetzung in Deutsch k\u00f6nnte also wie folgt aussehen<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">SELECT x FROM Text2Translate x JOIN x.translations translation WHERE translation.language = \u2018DE\u2018\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Aber Achtung<\/h2>\n\n\n\n<p>Dies Anfrage liefert unvollst\u00e4ndige Objekte. \u00dcbersetzungen 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\u00fcrde die Abfrage ohne die @JoinFetch in der Entit\u00e4t erstellt, w\u00fcrde der JPA-Provider nur die Text2Translate Basisobjekte in der ersten Abfrage erhalten und dann \u00fcber den PK alle \u00dcbersetzungen nachladen und somit vollst\u00e4ndige Objekte erzeugen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Ergebnis<\/h2>\n\n\n\n<p>@JoinFetch kann erhebliche Performance Gewinne bringen, man muss aber sehr genau aufpassen, welche Abfragen gestellt werden.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Umgebung Eine M\u00f6glichkeit das 1:n Problem bei JPA Zugriffen zu l\u00f6sen ist es, die abh\u00e4ngigen Werte einer Entit\u00e4t in einer Abfrage von der Datenbank zu bekommen. Hierf\u00fcr bietet Eclipselink die Annotation @JoinFetch. @Entity public class Text2Translate extends Serializable { &#8230; @OneToMany(cascade = CascadeType.ALL, mappedBy = &#8222;&#8230;&#8220;, fetch = FetchType.EAGER) @JoinFetch(value = JoinFetchType.OUTER) private List&lt;Translation&gt; translations [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,7],"tags":[],"class_list":["post-134","post","type-post","status-publish","format-standard","hentry","category-jee","category-wildfly"],"_links":{"self":[{"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=\/wp\/v2\/posts\/134","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=134"}],"version-history":[{"count":1,"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=\/wp\/v2\/posts\/134\/revisions"}],"predecessor-version":[{"id":135,"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=\/wp\/v2\/posts\/134\/revisions\/135"}],"wp:attachment":[{"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=134"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=134"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=134"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}