2016-06-10 5 views
4

I Eclipse verwenden und den folgenden Code:JPA: Warum faul Felder geladen werden, wenn EntityManager geschlossen ist

public Temp getTemp() { 
    EntityManager em=emf.createEntityManager(); 
    String queryString="SELECT a FROM Temp a"; 
    EntityGraph<Temp> eg = em.createEntityGraph(Temp.class); 
    eg.addAttributeNodes("id"); 
    //eg.addAttributeNodes("name"); 
    Query query = em.createQuery(queryString); 
    query.setHint("javax.persistence.fetchgraph", eg); 
    List<Temp> items=query.getResultList(); 
    em.close();// ENTITYMANAGER IS CLOSED 
    return items.get(0); 
} 

public void temp(){ 
    Temp temp=getTemp(); 
    System.out.println("id:"+temp.getId()); 
    System.out.println("name:"+temp.getName()); 
} 

Wie Sie aus dem Code sehen wir nur id laden. Wenn wir jedoch temp.getName() onemore ausführen, wird die SQL-Abfrage ausgeführt und die notwendigen Daten werden geladen. Warum? Wir haben den Entity Manager geschlossen. Ich habe erwartet, eine Ausnahme bei temp.getName() zu bekommen.

EDIT 1 Nach einigen Recherchen ich folgendes herausgefunden - das Verhalten, die ich oben beschrieben ist tatsächlich, wenn webt statisch (<property name="eclipselink.weaving" value="static"/> + de.empulse.eclipselink Weben Plugin). Wenn jedoch das Weben ist dynamisch (<property name="eclipselink.weaving" value="true"/>) bekomme ich Ausnahme:

java.lang.ClassNotFoundException: org.eclipse.persistence.internal.jpa.EntityManagerImpl not found by com.temp [57] 
    at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1574) 
    at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:79) 
    at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2018) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) 
    at com.temp.Temp._persistence_checkFetched(Temp2.java) 
    at com.temp.Temp._persistence_get_name(Temp2.java) 
    at com.temp.Temp.getName(Temp.java:44) 

So Frage hier bewegt: Eclipselink: Difference between static and dynamic weaving

+1

Mögliches Duplikat von [JPA EntityManager.detach() lädt immer noch faule Beziehungen] (http://stackoverflow.com/questions/37562870/jpa-entitymanager- detach-still-load-lazy-relations) –

Antwort

2

Denn das Eclipse ist und unterstützt freistehenden Laden von Feldern ... also etwas, das nicht in die JPA-Spezifikation und ist vollständig nicht portabel (dh nicht in anderen Implementierungen unterstützt). Der Zustand "gelöst" ist nicht wirklich "gelöst" und behält den Kontakt mit der EntityManagerFactory bei. Wenn Sie den EMF schließen, werden sie wirklich "getrennt".

Siehe this email chain discussing the "feature". Es wird nicht erwähnt, wie man es abschalten kann (so dass man ein tragbares Verhalten haben kann), und tatsächlich bittet die Person darum, es anzufordern! Die Frage, warum die JPA-TCK nicht nach tragbarem Verhalten sucht, ist eine Frage von Oracle ... aber bitte, das EclipseLink-Team hat die TCK geschrieben, nicht wahr ...

Um zu bleiben tragbar Sie werden gemäß der JPA-Spezifikation abtrennen und sich nicht auf ein solches Verhalten verlassen

+0

Vielleicht wissen Sie - gibt es eine Möglichkeit, es "losgelöst" zu machen, ohne Fabrik zu schließen, weil es nicht möglich ist, die Fabrik zu solchen Zwecken zu schließen? –

+0

Bitte, siehe EDIT 1 –