2015-12-10 12 views
5

ultimamente ho sperimentato un po 'con JPA per cercare di capire un po' di più l'intero framework. Sto usando Eclipselink come provider JPA.Metodo di chiamata JPA su raccolta lenta (non caricata) in caso di distacco non funzionante come previsto in Eclipselink

Ho due entità con una relazione @OneToMany (una persona ha molti indirizzi) che è pigro caricato.

Quando carico un'entità persona, lo scollego e quindi provo ad accedere agli indirizzi (non caricati) ... funziona come un incantesimo. Durante il debug posso vedere che una query di database viene eseguita quando si esegue il metodo size() della lista di indirizzi.

Non capisco perché funzioni. Mi aspetterei un qualche tipo di eccezione. Ho letto un bel po 'su jpa e simili negli ultimi giorni (cioè this link) ma tutto mi ha portato alla conclusione che non dovrebbe funzionare.

Qualcuno può spiegare perché funziona?

@Stateless 
public class Test { 
    @PersistenceContext(unitName="TestPU") EntityManager em; 

    public void test() { 
     Person person = em.find(Person.class, 1); 

     System.out.println(person); 

     System.out.println("em.contains(person): " + em.contains(person); 

     em.detach(person); 

     System.out.println("em.contains(person): " + em.contains(person); 

     person.getAddresses().size(); 

     System.out.println("em.contains(person): " + em.contains(person); 

     System.out.println(person); 

    } 
} 

Il registro risultante sarebbe

DEBUG: SELECT ... from PERSON WHERE (id = ?) 
Person{id=1, name=Test, addresses={IndirectList: not instantiated}} 
em.contains(person): true 
em.contains(person): false 
DEBUG: SELECT ... FROM ADDRESSES where (address_fk = ?) 
em.contains(person): false 
Person{id=1, name=Test, addresses={[Address{id=10, city=Testcity}]}} 
+3

perché con EclipseLink non stanno realmente "staccando" gli oggetti nel modo in cui le specifiche JPA intendono (cioè disconnettendosi dal DB), quindi conservano le informazioni di connessione ... quindi recupera il campo (anche se non dovrebbe se veramente "distaccato"). Se hai effettuato la stessa operazione su altri fornitori JPA, genererebbe un'eccezione in genere se un campo non fosse stato rimosso. –

+0

È possibile controllare, se l'entità è correttamente staccata, chiamando [em.contains] (http://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#contains%28java.lang.Object % 29) –

risposta

1

Come descritto here distacco rimuove l'Ente dal contesto in modo che non è più gestito. Dal momento che il contesto è ancora disponibile, tuttavia, le raccolte pigro non codificate possono comunque essere recuperate se necessario, e EclipseLink lo ritiene più prezioso di un'eccezione. È considerata una funzionalità di EclipseLink ed è consentita dalle specifiche JPA, nonostante altri provider non abilitino il comportamento per impostazione predefinita.

+0

Grazie per il chiarimento. Anche se non sono sicuro che le specifiche JPA consentano questo evento. Non sono un esperto nel leggere le specifiche, ma per quanto comprendo la seguente citazione non consente il comportamento. Lo stato disponibile di un'istanza associata PU MAY SOLO accedere se l'istanza associata è disponibile. (JSR 338 sezione 3.2. 7 Entità distaccate) – Filou

+0

Questo indica che il comportamento non è definito, non che richiede un'eccezione e EclipseLink è l'implementazione di riferimento per la specifica. Non è sicuro accedere alla relazione in seguito poiché le Entità possono essere serializzate in qualsiasi momento, interrompendo la connessione al contesto (anche se è ancora aperto). – Chris

+0

Hai ragione, non è proibito. Non c'è _deve non_. Ho solo bisogno di essere un po 'più abituato a leggere le specifiche. Grazie ancora per i chiarimenti! – Filou

Problemi correlati