2010-04-25 23 views
16

Aggiungo entità al mio database e funziona perfettamente. Ma quando recupero l'Elenco, ottengo la vecchia entità, le nuove entità che aggiungo non vengono mostrate fino a quando non annullo l'applicazione e la ridistribuisco di nuovo. Questo significa che le mie entità sono memorizzate nella cache per impostazione predefinita? Ma, non ho fatto alcuna impostazione per le entità di memorizzazione nella cache nel mio persistence.xml o qualsiasi file di questo tipo.Le entità sono memorizzate nella cache in jpa per impostazione predefinita?

Ho anche provato a chiamare flush(), refresh() e unione(). Ma mostra ancora solo le vecchie entità. Mi sto perdendo qualcosa? Mi aiuti per favore.

risposta

16

Benvenuti in JPA. Se lo usi, significa che avrai problemi enormi se aggiorni il database al di fuori di JPA a meno che tu non sappia cosa stai facendo e stai molto attento. Ciò significa che devi capire come svuotare qualsiasi entità memorizzata nella cache in modo che possano essere ricaricate.

Fondamentalmente, non aggiornare le entità al di fuori di JPA se è possibile a tutti di aiutare e se lo si dovrà probabilmente entrare nel funzionamento del modello di caching utilizzato dal proprio provider JPA. Se hai bisogno di aggiornare al di fuori di JPA molto spesso, JPA probabilmente non è la scelta giusta per te.

+1

Ma non sto aggiornando il database al di fuori di JPA. Ho usato il metodo persist di jpa e il record è visto nel database. Ma quando recupero la lista, non vedo l'entità appena aggiunta. Mi aiuti per favore. – TCM

+0

Inoltre, ancora più strano è il fatto che se cambio il provider da TopLink a EclipseLink, tutto funziona correttamente! Con TopLink solo questo problema sta arrivando. Sto usando Netbeans 6.8 e Glassfish v3. – TCM

+0

@Nitesh stai usando le transazioni? Se sì, li stai commettendo? – cletus

11

Questo significa che le mie entità sono memorizzate nella cache per impostazione predefinita?

JPA 1.0 non definisce una cache L2 ("cache condivisa"), JPA 1.0 definisce solo una cache L1 ("cache transazionale") ma i fornitori APP può supportare una cache oggetto condiviso, e più fare. Questo è il caso di TopLink Essentials che supporta la cache L1 e L2 tramite JPA Extensions for Caching (per JVM).

Ora, come spiegato nella grande articolo Understanding the cache of TopLink Essentials(GlassFish JPA):

  • Tutte EntityManagers da medesime unità condivide la persistenza della cache di sessione (che è come TopLink chiama la cache di 2 ° livello).
  • La cache di sessione è attivata per impostazione predefinita.
  • Se sono presenti modifiche/eliminazioni di entità nel contesto di persistenza, esse vengono sincronizzate con la cache di sessione dopo una transazione impegnata, quindi lo stato della cache di sessione viene aggiornato (o tale cache non sarebbe utilizzabile affatto) .

Quindi ci deve essere qualcos'altro che non va nella configurazione. È possibile provare non disabilitare la cache di sessione condivisa a scopo di test (e solo a scopo di test) aggiungendo la seguente proprietà:

<property name="toplink.cache.shared.default" value="false"/> 

ma sarei sorpreso se questo cambia nulla. Come ho detto, penso che ci sia un altro problema da qualche parte.

PS: Questo non risponde alla domanda ma, se si utilizza GlassFish v3, perché non si utilizza EclipseLink?

Aggiornamento: rispondere a un commento del PO

Quindi, se persisto record di dipendenti, allora è visto nel database, ma non nella collezione di dipendenti in reparto fino a quando ho esplicitamente inserirlo alla raccolta dei dipendenti. È questo passaggio necessario?

Beh, se non si crea il collegamento tra entità a livello di Java, JPA non sarà in grado di crearla al database (JPA solo fa quello che gli dice di fare). Quindi, , è necessario creare il collegamento e, in caso di un'associazione bidirezionale, è anche necessario impostare entrambi i lati del collegamento (ad esempio aggiungere employee alla raccolta di dipendenti su Department e impostare lo department di un Employee).

+3

Ciao Pascal Thivent, fornitore di EclipseLink nel mio persistence.xml e tutto ha funzionato bene. Ma ho ancora un altro dubbio, che ho chiesto anche a cletus: - Fondamentalmente, quello che succede è dire che ci sono tavoli dei dipendenti e dei reparti. Il tavolo del dipartimento ha una collezione di dipendenti. Quindi, se continuo a registrare un dipendente, allora viene visto nel database ma non nella raccolta di dipendenti nel reparto finché non lo aggiungo esplicitamente alla raccolta di dipendenti. È questo passaggio necessario? se ho 10 tabelle relative a un'entità. Devo aggiungerlo alla raccolta di tutti e 10 i tavoli? È troppo noioso? – TCM

1

JPA 2.0 definisce una cache condivisa (L2), ma non specifica il valore predefinito. EclipseLink abilita il caching di default, altri non lo fanno.

Un EntityManager avrà sempre una cache di contesto di persistenza (L1) finché non si chiama clear() o ne si crea uno nuovo.

È possibile disattivare la cache condivisa,

Sede, http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching

Ma il problema è che non si è mantenere entrambi i lati del vostro rapporto. Quando si imposta l'1-1 è necessario aggiungere 1 m, altrimenti gli oggetti non sono validi.

Per ulteriori informazioni sulla cache di vedere,

http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching

0

Sto usando il contesto EclipseLink e ejb, ho scoperto che quando interrogo entità, sarà automaticamente memorizzata nella cache, ma io eseguire anche una funzione per modificare record nel database, in modo posso ottenere i vecchi dati nella cache, in modo da disattivare la cache aggiungendo quanto segue al file persistence.xml:

<shared-cache-mode>NONE</shared-cache-mode> 

funziona!

Problemi correlati