Tipo di recupero predefinito per uno-a-uno, molti-a-uno e uno-a-molti in Hibernate


103

Qual è il tipo di recupero predefinito nelle mappature di ibernazione?

Quello che ho avuto modo di sapere dopo aver esplorato è:

  • per uno a uno è desideroso .
  • per uno-a-molti è pigro .

Ma dopo averlo testato in Eclipse, era impaziente di tutto.

Dipende se utilizzo JPA o Hibernate?


1
Nel caso in cui tu sia ancora coinvolto in argomenti JPA, ho aggiornato la tua domanda con una nuova risposta, poiché quelle vecchie non sono aggiornate per l'attuale versione di Hibernate.
Alexander Rühl

Risposte:


193

Dipende se stai usando JPA o Hibernate.

Dalla specifica JPA 2.0 , i valori predefiniti sono:

OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER

E in ibernazione, tutto è pigro

AGGIORNARE:

L'ultima versione di Hibernate è allineata con le impostazioni predefinite JPA sopra.


11
"E in ibernazione, tutto è pigro" a quanto pare è cambiato nelle ultime versioni. Si prega di vedere la risposta di Alexander Rühl di seguito .
Dinei

1
Hibernate è una delle implementazioni JPA, quindi una volta che usi Hibernate, stai usando JPA :)
xenteros

Questa è una query popolare. @Ashish Agarwal Puoi aggiornare l'ultima riga della tua risposta. In Hibernate non è pigro per tutti ora.
Saurabh Tiwari

Aggiornato il post per quanto riguarda l'ultimo comportamento di Hibernate.
M Anouti,

C'era un aggiornamento, sostenendo che eager è il tipo di recupero predefinito per ogni mappatura, che è confutato dal capitolo 11.3 sia nella documentazione di Hibernate 5.x che nella nuova 6.x, quindi ho annullato la modifica. Inoltre, è contro la raccomandazione di non avere l'entusiasmo automatico, poiché ciò significherebbe probabilmente selezionare l'intero database durante il recupero di un singolo oggetto.
Alexander Rühl,

51

So che le risposte erano corrette al momento della domanda, ma poiché le persone (come me in questo momento) continuano a trovarle chiedendosi perché il loro WildFly 10 si stesse comportando in modo diverso, mi piacerebbe fornire un aggiornamento per l'attuale Hibernate 5 versione .x:

Nella Guida per l'utente di Hibernate 5.2 è indicato nel capitolo 11.2. Applicazione di strategie di recupero :

Il consiglio di Hibernate è di contrassegnare staticamente tutte le associazioni come pigre e di utilizzare strategie di recupero dinamico per l'entusiasmo. Questo è sfortunatamente in contrasto con la specifica JPA che definisce che tutte le associazioni uno-a-uno e molti-a-uno dovrebbero essere recuperate con entusiasmo per impostazione predefinita . Hibernate, in qualità di provider JPA, onora tale impostazione predefinita.

Quindi anche Hibernate si comporta come Ashish Agarwal affermato sopra per JPA:

OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER

(vedi specifica JPA 2.1 )


E se usassimo l'ibernazione nativa invece di JPA impl, agisse allo stesso modo?
jMounir

@jMounir: Beh, non l'ho provato, ma dal momento che Hibernate afferma che si comporta come definito in JPA, non vedo perché sarebbe diverso quando si usa Hibernate per se stesso. In entrambi i casi è possibile ignorare la strategia predefinita.
Alexander Rühl

15

Per rispondere alla tua domanda, Hibernate è un'implementazione dello standard JPA. Hibernate ha le sue stranezze di funzionamento, ma come per i documenti di Hibernate

Per impostazione predefinita, Hibernate utilizza il recupero della selezione pigra per le raccolte e il recupero lento del proxy per le associazioni a valore singolo. Queste impostazioni predefinite hanno senso per la maggior parte delle associazioni nella maggior parte delle applicazioni.

Quindi Hibernate caricherà sempre qualsiasi oggetto usando una strategia di recupero pigro, indipendentemente dal tipo di relazione che hai dichiarato. Utilizzerà un proxy lento (che dovrebbe essere non inizializzato ma non nullo) per un singolo oggetto in una relazione uno-a-uno o molti-a-uno e una raccolta nulla che si idraterà con valori quando si tenta di accedervi .

Dovrebbe essere chiaro che Hibernate tenterà di riempire questi oggetti con valori solo quando tenterai di accedere all'oggetto, a meno che tu non specifichi fetchType.EAGER.


0

Per le associazioni a valore singolo, ad esempio uno-a-uno e molti-a-uno: -
Default Lazy = proxy
Lazy loading proxy : - Ciò implica che viene caricato un oggetto proxy dell'entità associata. Ciò significa che solo l'id che connette le due entità viene caricato per l'oggetto proxy dell'entità associata.
Ad esempio: A e B sono due entità con associazione Molti a uno. cioè: possono esserci più A per ogni B. Ogni oggetto di A conterrà un riferimento di B.
`

public class A{
    int aid;
    //some other A parameters;
    B b;
}
public class B{
    int bid;
     //some other B parameters;
}

`
La relazione A conterrà colonne (aiuto, offerta, ... altre colonne dell'entità A).
La relazione B conterrà colonne (offerta, ... altre colonne dell'entità B) Il

proxy implica che quando A viene recuperato, solo l'ID viene recuperato per B e memorizzato in un oggetto proxy di B che contiene solo ID. L'oggetto proxy di B è un oggetto di una classe proxy che è una sottoclasse di B con solo campi minimi. Poiché l'offerta è già parte della relazione A, non è necessario attivare una query per ottenere un'offerta dalla relazione B. Altri attributi dell'entità B vengono caricati pigramente solo quando si accede a un campo diverso da bid.

Per le raccolte, cioè molti a molti e uno a molti: -
Predefinito Lazy = true


Notare anche che la strategia di recupero (seleziona, partecipa ecc.) Può prevalere su lazy. cioè: se lazy = 'true' e fetch = 'join', il recupero di A recupererà anche B o Bs (in caso di raccolte). Puoi capire il motivo se ci pensi.
Il recupero predefinito per l'associazione a valore singolo è "join".
Il recupero predefinito per le raccolte è "seleziona". Si prega di verificare le ultime due righe. L'ho dedotto logicamente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.